~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/tcl/indiva/lib/ascp.tcl

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 # ascp.tcl --
  2 #
  3 #       An implementation of ASCP v3.0 for Active Service Framework.    
  4 #
  5 # Copyright (c) 1998-2002 The Regents of the University of California.
  6 # All rights reserved.
  7 #
  8 # Redistribution and use in source and binary forms, with or without
  9 # modification, are permitted provided that the following conditions are met:
 10 #
 11 # A. Redistributions of source code must retain the above copyright notice,
 12 #    this list of conditions and the following disclaimer.
 13 # B. Redistributions in binary form must reproduce the above copyright notice,
 14 #    this list of conditions and the following disclaimer in the documentation
 15 #    and/or other materials provided with the distribution.
 16 # C. Neither the names of the copyright holders nor the names of its
 17 #    contributors may be used to endorse or promote products derived from this
 18 #    software without specific prior written permission.
 19 #
 20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 23 # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
 24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 30 #
 31 
 32 import AnnounceListenManager 
 33 import ASCPPacket
 34 
 35 #----------------------------------------------------------------------
 36 # Class:
 37 #   ASCP
 38 # Description:
 39 #   Base class for active service control protocol v3 in active 
 40 #   service framework.
 41 # Members:
 42 #   lastann_ --
 43 #       An array indexed by agent spec, that contains time the last 
 44 #       announcement was made to the corresponding agent.  Time are
 45 #       stored as absolute time (gettimeofday) and as ascii time (
 46 #       clock format).
 47 #   avgdelta_ --
 48 #       An array indexed by agent spec, that contains average time 
 49 #       between announcement from the corresponding agent.
 50 #----------------------------------------------------------------------
 51 Class ASCP -superclass AnnounceListenManager
 52 
 53 #----------------------------------------------------------------------
 54 # Method:
 55 #   ASCP init
 56 # Description:
 57 #   Initialize various members and timer.
 58 # Arguments:
 59 #   session -- ip address and port number of the target session.
 60 #   bw -- bandwidth limit of the protocol.
 61 #----------------------------------------------------------------------
 62 ASCP instproc init { session bw } {
 63     set mtu 1024
 64 
 65     $self next $session $mtu
 66 
 67     set o [$self options]
 68     $o add_default startupWait 60
 69 
 70     $self instvar as_bw_ as_spec_
 71     set as_bw_ $bw
 72     set as_spec_ $session
 73 
 74     $self instvar timer_list_
 75     set timer_list_ {}
 76 
 77     $self set packet_ [new ASCPPacket]
 78 }
 79 
 80 
 81 #----------------------------------------------------------------------
 82 # Method:
 83 #   ASCP destroy
 84 # Description:
 85 #   Cleanup "after" callback.
 86 #----------------------------------------------------------------------
 87 ASCP instproc destroy {} {
 88     $self instvar agents_
 89     foreach id [array names agents_] {
 90         $self del_agent $id
 91     }
 92     $self bye
 93     $self next
 94 }
 95 
 96 
 97 #----------------------------------------------------------------------
 98 # Method:
 99 #   ASCP version
100 # Description:
101 #   Return the version string of the current Active Service Framework.
102 #----------------------------------------------------------------------
103 ASCP proc version {} {
104     return 3.0
105 }
106 
107 
108 #----------------------------------------------------------------------
109 # Method:
110 #   ASCP version
111 # Description:
112 #   Return the version string of the current Active Service Framework.
113 #----------------------------------------------------------------------
114 ASCP instproc bandwidth {} {
115     return [$self set as_bw_] 
116 }
117 
118 #----------------------------------------------------------------------
119 # Method:
120 #   ASCP send_announcement
121 # Description:
122 #   Construct an announcement, and send it.  
123 #----------------------------------------------------------------------
124 ASCP public send_announcement {} {
125     return
126 }
127 
128 
129 #----------------------------------------------------------------------
130 # Method:
131 #   ASCP bye
132 # Description:
133 #   Construct a BYE announcement and announce it.
134 #----------------------------------------------------------------------
135 ASCP instproc bye {} {
136     set packet [new ASCPPacket]
137     $packet agent_type [$self agent_type]
138     $packet agent_type [$self agent_id]
139     $packet operation "bye"
140 
141     $self announce [$packet to_string]
142     delete $packet
143 }
144 
145 
146 #----------------------------------------------------------------------
147 # Method:
148 #   ASCP agent_id
149 # Description:
150 #   Return a string that represent an instance of the current agent.
151 #----------------------------------------------------------------------
152 ASCP public agent_id {} {
153     return "[pid]@[info hostname]:[$self control_port]"
154 }
155 
156 
157 #----------------------------------------------------------------------
158 # Method:
159 #   ASCP agent_type
160 # Description:
161 #   Subclass should overwrite this to return agent type.
162 #----------------------------------------------------------------------
163 ASCP public agent_type {} {
164     return ""
165 }
166 
167 #----------------------------------------------------------------------
168 # Method:
169 #   ASCP process_packet
170 # Description:
171 #   Agent specific handling of message.  Subclass should overwrite 
172 #   this.  NOTE: This is responsible for freeing $packet.
173 # Arguments: 
174 #   addr --
175 #     Address where this packet comes from.
176 #   packet --
177 #     The ASCP packet received.
178 #----------------------------------------------------------------------
179 ASCP public process_packet {addr packet} {
180     # delete $packet
181     return ""
182 }
183 
184 #----------------------------------------------------------------------
185 # Method:
186 #   ASCP args
187 # Description:
188 #   Subclass should overwrite this to return agent specific data.
189 #----------------------------------------------------------------------
190 ASCP public args {} {
191     return ""
192 }
193 
194 
195 #----------------------------------------------------------------------
196 # Method:
197 #   ASCP ssg_port
198 # Description:
199 #   Subclass should overwrite this to return port number to a soft state
200 #   gateway.
201 #----------------------------------------------------------------------
202 ASCP public ssg_port {} {
203     return "-"
204 }
205 
206 
207 #----------------------------------------------------------------------
208 # Method:
209 #   ASCP service_location
210 # Description:
211 #   Subclass should overwrite this to return the service location.
212 #----------------------------------------------------------------------
213 ASCP instproc service_location {} {
214     return "-"
215 }
216 
217 
218 #----------------------------------------------------------------------
219 # Method:
220 #   ASCP service_type
221 # Description:
222 #   Subclass should overwrite this to return the service type.
223 #----------------------------------------------------------------------
224 ASCP instproc service_type {} {
225     return "-"
226 }
227 
228 
229 #----------------------------------------------------------------------
230 # Method:
231 #   ASCP service_instance
232 # Description:
233 #   Subclass should overwrite this to return the service type.
234 #----------------------------------------------------------------------
235 ASCP instproc service_instance {} {
236     return "-"
237 }
238 
239 
240 
241 #----------------------------------------------------------------------
242 # Method:
243 #   ASCP recv_announcement
244 # Description:
245 #   Called when an announcement is received.  The announcement is parsed
246 #   and special cases are handled (DEATH, BYE, wrong version).  The method 
247 #   "process_packet {}" is then called to process other general messages.
248 # Arguments:
249 #   addr -- The address where this announcement came from.
250 #   port -- The port number where this announcement came from.
251 #   data -- The data contained in this announcement.
252 #   size -- The length of data in bytes.
253 #----------------------------------------------------------------------
254 ASCP instproc recv_announcement { addr port data size } {
255     $self instvar lastann_ sdp_ agents_ packet_
256 
257     # This HAS TO go. We should create one ASCPPacket object, and reuse 
258     # it over and over again.
259     set packet $packet_
260 
261     set result [$packet from_string $data]
262     if {$result == "invalid version"} {
263         $self error "WARNING: received non-ASCP v[$class version] announcement from $addr."
264         return
265     }
266 
267     set agent_type [$packet agent_type]
268     set agent_id   [$packet agent_id]
269     set op         [$packet operation]
270 
271     $self timers add_sample $size
272 
273     switch -exact -- $op {
274         "kill" {
275             set arg [$packet args]
276             if { $arg == [$self agent_type] } {
277                 $self error "Received death packet from $agent_id at $addr - exiting."
278                 $self bye
279                 exit 0
280             }
281             $self process_packet $addr $packet 
282         }
283         "bye" {
284             $self del_agent $agent_id
285             $self process_packet $addr $packet
286         }
287         default {
288             set srv_name  [$packet service_type]
289             set srv_inst  [$packet service_instance]
290             set ad        [$packet args]
291 
292             if {![info exists agents_($agent_id)]} {
293                 # new agent
294                 $self timers add_src
295                 set agents_($agent_id) [new MashSoftState/Adaptive \
296                     $addr 10000 "$self del_agent $agent_id" 8]
297                 #MashLog info "add agent $agent_id"
298             } else {
299                 $agents_($agent_id) refresh
300                 #MashLog info "refresh agent $agent_id"
301             }
302             $self process_packet $addr $packet
303         }
304     }
305 }
306 
307 
308 #----------------------------------------------------------------------
309 # Method:
310 #   ASCP del_agent
311 # Description:
312 #   Assume that the agent specified by $agent_id is dead.  Clean up all
313 #   states corresponding to that agent.
314 # Arguments:
315 #   agent_id -- 
316 #       Specification to the agent to be deleted.
317 #----------------------------------------------------------------------
318 ASCP instproc del_agent { agent_id } {
319     $self instvar agents_ 
320     if ![info exists agents_($agent_id)] {
321         # puts "hm: agent $agent_id doesn't exist!"
322         return
323     }
324     # MashLog info "delete agent $agent_id"
325 
326     delete $agents_($agent_id)
327     unset agents_($agent_id)
328     $self timers del_src 
329 }
330 
331 
332 #----------------------------------------------------------------------
333 # Method:
334 #   ASCP error
335 # Description:
336 #   Print an error message.  Subclass may want to overwrite this so
337 #   that it is printed to somewhere else, for e.g. a log file.
338 # Arguments:
339 #   msg -- 
340 #     The error message
341 #----------------------------------------------------------------------
342 ASCP instproc error {msg} {
343     puts stderr $msg
344 }
345 
346 
347 ASCP instproc as_args {} {
348     $self instvar as_spec_ as_bw_
349     return "-as_spec $as_spec_ -as_bw $as_bw_"
350 }
351 
352 ASCP instproc register {addr packet} {
353 #    error "register should not be called"
354 }
355 ASCP instproc unregister {addr packet} {
356 #    error "unregister should not be called"
357 }
358 # Default control port for rpc
359 # Subclass should override this to use different port.
360 ASCP instproc control_port { } {
361     return 9502
362 }
363 ASCP instproc add_timer {timer} {
364     $self instvar timer_list_
365     if {[lsearch $timer_list_ $timer] == -1} {
366         lappend timer_list_ $timer
367     }
368 }
369 ASCP instproc del_timer {timer} {
370     $self instvar timer_list_
371     set x [lsearch $timer_list_ $timer]
372     if {$x != -1} {
373         set timer_list_ [lreplace $timer_list_ $x $x]
374     }
375 }
376 ASCP instproc timers {op args} {
377     $self instvar timer_list_
378     foreach t $timer_list_ {
379         if {[$t has_method $op]} {
380             eval $t $op $args
381         }
382     }
383 }
384 # vim:ts=8:sw=4:expandtab
385 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.