132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: July 2004: Initial release
|
|
8
|
|
9 author: Kris
|
|
10
|
|
11 *******************************************************************************/
|
|
12
|
|
13 module tango.net.cluster.NetworkClient;
|
|
14
|
|
15 private import tango.time.Clock;
|
|
16
|
|
17 private import tango.core.Exception;
|
|
18
|
|
19 public import tango.net.cluster.model.ICluster;
|
|
20
|
|
21 public import tango.net.cluster.NetworkMessage,
|
|
22 tango.net.cluster.NetworkRegistry;
|
|
23
|
|
24 /*******************************************************************************
|
|
25
|
|
26 The base class for all cluster clients (such as CacheInvalidator)
|
|
27 which acts simply as a container for the operating IChannel and
|
|
28 the configured ICluster. The former specifies something akin to
|
|
29 a 'topic' in the pub/sub world, while the latter provides access
|
|
30 to the underlying functional substrate (the QOS implementation).
|
|
31
|
|
32 *******************************************************************************/
|
|
33
|
|
34 class NetworkClient
|
|
35 {
|
|
36 private IChannel channel_;
|
|
37 private ICluster cluster_;
|
|
38
|
|
39 public static NetworkMessage EmptyMessage;
|
|
40
|
|
41 static this ()
|
|
42 {
|
|
43 NetworkRegistry.shared.enroll (EmptyMessage = new NetworkMessage);
|
|
44 }
|
|
45
|
|
46 /***********************************************************************
|
|
47
|
|
48 Construct this client with the specified channel and cluster.
|
|
49 The former specifies something akin to a 'topic', whilst the
|
|
50 latter provides access to the underlying functional substrate
|
|
51 (the QOS implementation). A good way to think about channels
|
|
52 is to map them directly to a class name. That is, since you
|
|
53 send and recieve classes on a channel, you might utilize the
|
|
54 class name as the channel name (this.classinfo.name).
|
|
55
|
|
56 ***********************************************************************/
|
|
57
|
|
58 this (ICluster cluster, char[] channel)
|
|
59 {
|
|
60 assert (cluster);
|
|
61 assert (channel.length);
|
|
62
|
|
63 cluster_ = cluster;
|
|
64 channel_ = cluster.createChannel (channel);
|
|
65 }
|
|
66
|
|
67 /***********************************************************************
|
|
68
|
|
69 Return the channel we're tuned to
|
|
70
|
|
71 ***********************************************************************/
|
|
72
|
|
73 IChannel channel ()
|
|
74 {
|
|
75 return channel_;
|
|
76 }
|
|
77
|
|
78 /***********************************************************************
|
|
79
|
|
80 Return the cluster specified during construction
|
|
81
|
|
82 ***********************************************************************/
|
|
83
|
|
84 ICluster cluster ()
|
|
85 {
|
|
86 return cluster_;
|
|
87 }
|
|
88
|
|
89 /***********************************************************************
|
|
90
|
|
91 Return the current time
|
|
92
|
|
93 ***********************************************************************/
|
|
94
|
|
95 Time time ()
|
|
96 {
|
|
97 return Clock.now;
|
|
98 }
|
|
99
|
|
100 /***********************************************************************
|
|
101
|
|
102 Return the Log instance
|
|
103
|
|
104 ***********************************************************************/
|
|
105
|
|
106 Logger log ()
|
|
107 {
|
|
108 return cluster_.log;
|
|
109 }
|
|
110
|
|
111 /***********************************************************************
|
|
112
|
|
113 Create a channel with the specified name. A channel
|
|
114 represents something akin to a publush/subscribe topic,
|
|
115 or a radio station. These are used to segregate cluster
|
|
116 operations into a set of groups, where each group is
|
|
117 represented by a channel. Channel names are whatever you
|
|
118 want then to be; use of dot notation has proved useful
|
|
119 in the past. In fact, a good way to think about channels
|
|
120 is to map them directly to a class name. That is, since you
|
|
121 typically send and recieve classes on a channel, you might
|
|
122 utilize the class name as the channel (this.classinfo.name).
|
|
123
|
|
124 ***********************************************************************/
|
|
125
|
|
126 IChannel createChannel (char[] name)
|
|
127 {
|
|
128 return cluster_.createChannel (name);
|
|
129 }
|
|
130 }
|
|
131
|
|
132 /*******************************************************************************
|
|
133
|
|
134 This exception is thrown by the cluster subsystem when an attempt
|
|
135 is made to place additional content into a full queue
|
|
136
|
|
137 *******************************************************************************/
|
|
138
|
|
139 class ClusterFullException : ClusterException
|
|
140 {
|
|
141 this (char[] msg)
|
|
142 {
|
|
143 super (msg);
|
|
144 }
|
|
145 }
|
|
146
|
|
147 /*******************************************************************************
|
|
148
|
|
149 This exception is thrown by the cluster subsystem when an attempt
|
|
150 is made to converse with a non-existant cluster, or one where all
|
|
151 cluster-servers have died.
|
|
152
|
|
153 *******************************************************************************/
|
|
154
|
|
155 class ClusterEmptyException : ClusterException
|
|
156 {
|
|
157 this (char[] msg)
|
|
158 {
|
|
159 super (msg);
|
|
160 }
|
|
161 }
|
|
162
|