00001 /******************************************************************************* 00002 00003 @file Client.d 00004 00005 Copyright (C) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 00027 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00028 00029 00030 @version Initial version, July 2004 00031 @author Kris 00032 00033 00034 *******************************************************************************/ 00035 00036 module mango.cluster.Client; 00037 00038 private import mango.base.System; 00039 00040 private import mango.io.Exception; 00041 00042 public import mango.cluster.Message; 00043 00044 public import mango.cluster.model.ICluster; 00045 00046 /******************************************************************************* 00047 00048 The base class for all cluster clients (such as CacheInvalidator) 00049 which acts simply as a container for the operating IChannel and 00050 the configured ICluster. The former specifies something akin to 00051 a 'topic' in the pub/sub world, while the latter provides access 00052 to the underlying functional substrate (the QOS implementation). 00053 00054 *******************************************************************************/ 00055 00056 class Client 00057 { 00058 private IChannel channel; 00059 private ICluster cluster; 00060 00061 public static NullMessage EmptyMessage; 00062 00063 static this () 00064 { 00065 EmptyMessage = new NullMessage; 00066 } 00067 00068 /*********************************************************************** 00069 00070 Construct this client with the specified channel and cluster. 00071 The former specifies something akin to a 'topic', whilst the 00072 latter provides access to the underlying functional substrate 00073 (the QOS implementation). A good way to think about channels 00074 is to map them directly to a class name. That is, since you 00075 send and recieve classes on a channel, you might utilize the 00076 class name as the channel name (this.classinfo.name). 00077 00078 ***********************************************************************/ 00079 00080 this (ICluster cluster, char[] channel) 00081 in { 00082 assert (cluster); 00083 assert (channel.length); 00084 } 00085 body 00086 { 00087 this.cluster = cluster; 00088 this.channel = cluster.createChannel (channel); 00089 } 00090 00091 /*********************************************************************** 00092 00093 Return the channel we're tuned to 00094 00095 ***********************************************************************/ 00096 00097 IChannel getChannel () 00098 { 00099 return channel; 00100 } 00101 00102 /*********************************************************************** 00103 00104 Return the cluster specified during construction 00105 00106 ***********************************************************************/ 00107 00108 ICluster getCluster () 00109 { 00110 return cluster; 00111 } 00112 00113 /*********************************************************************** 00114 00115 Return the number of milliseconds since Jan 1st 1970 00116 00117 ***********************************************************************/ 00118 00119 long getTime () 00120 { 00121 return System.getMillisecs; 00122 } 00123 00124 /*********************************************************************** 00125 00126 Create a channel with the specified name. A channel 00127 represents something akin to a publush/subscribe topic, 00128 or a radio station. These are used to segregate cluster 00129 operations into a set of groups, where each group is 00130 represented by a channel. Channel names are whatever you 00131 want then to be; use of dot notation has proved useful 00132 in the past. In fact, a good way to think about channels 00133 is to map them directly to a class name. That is, since you 00134 typically send and recieve classes on a channel, you might 00135 utilize the class name as the channel (this.classinfo.name). 00136 00137 ***********************************************************************/ 00138 00139 IChannel createChannel (char[] name) 00140 { 00141 return cluster.createChannel (name); 00142 } 00143 } 00144 00145 /******************************************************************************* 00146 00147 This exception is thrown by the cluster subsystem when it runs 00148 into something unexpected. 00149 00150 *******************************************************************************/ 00151 00152 class ClusterException : IOException 00153 { 00154 /*********************************************************************** 00155 00156 Construct exception with the provided text string 00157 00158 ***********************************************************************/ 00159 00160 this (char[] msg) 00161 { 00162 super (msg); 00163 } 00164 } 00165 00166 /******************************************************************************* 00167 00168 This exception is thrown by the cluster subsystem when an attempt 00169 is made to place additional content into a full queue 00170 00171 *******************************************************************************/ 00172 00173 class ClusterFullException : ClusterException 00174 { 00175 /*********************************************************************** 00176 00177 Construct exception with the provided text string 00178 00179 ***********************************************************************/ 00180 00181 this (char[] msg) 00182 { 00183 super (msg); 00184 } 00185 } 00186 00187 /******************************************************************************* 00188 00189 This exception is thrown by the cluster subsystem when an attempt 00190 is made to converse with a non-existant cluster, or one where all 00191 cluster-servers have died. 00192 00193 *******************************************************************************/ 00194 00195 class ClusterEmptyException : ClusterException 00196 { 00197 /*********************************************************************** 00198 00199 Construct exception with the provided text string 00200 00201 ***********************************************************************/ 00202 00203 this (char[] msg) 00204 { 00205 super (msg); 00206 } 00207 } 00208