1 import AGLP
2 import MashTimer
3 import MashSoftState
4
5 #--------------------------------------------------------------------
6 # AGLP/Client
7 #
8 # Members :
9 #
10 # This class represent a client object in Degas Control Protocol (DCP)
11 # public methods :
12 #
13 # - start
14 # Starts the protocol by sending service request packet periodically.
15 #
16 # - stop
17 # Stop the protocol, by cancelling periodic timer. This causes
18 # the client to cease sending service request packet.
19 #
20 # - recv
21 # A callback which is activated whenever a packet is received.
22 #--------------------------------------------------------------------
23
24 Class AGLP/Client -superclass AGLP
25
26 AGLP/Client instproc init { application tcp_channel group mtu } {
27 $self instvar duplicate_counter_ log_file_ tcp_channel_
28 $self instvar config_ application_ num_of_restart_ pid_
29 $self next "C" $group $mtu
30
31 set num_of_restart_ 0
32 set duplicate_counter_ 0
33 set config_(SERVICE_REQUEST_PERIOD) 20000
34 set config_(FORGET_BEING_SERVED_PERIOD) 50000
35 set config_(ANNOUNCE_SERVICE_PERIOD) 30000
36 #set log_file_ [open "a.log" "a+"]
37 set application_ $application
38 $self set running_ 0
39
40 set tcp_channel_ $tcp_channel
41 set pid_ [pid]
42
43 # LOGGING
44 $self instvar handoff_log_
45 set handoff_log_ [open "handoff.log" w]
46 }
47
48 AGLP/Client instproc in_service {} {
49 $self instvar my_gateway_
50 if {[info exists my_gateway_]} {
51 if {[$my_gateway_ is_expired] == 0} {
52 return 1
53 }
54 }
55 return 0
56 }
57
58 AGLP/Client public start {} {
59 $self instvar request_time_
60 $self set running_ 1
61 $self send_service_request
62 $self start_service_request_announcement
63 set request_time_ [gettimeofday]
64 }
65
66
67 AGLP/Client public send { msg } {
68 $self next "DCP c $msg"
69 }
70
71
72 AGLP/Client public start_service_request_timer {} {
73 # $self instvar being_served_timer_ my_gateway_
74 $self instvar num_of_restart_
75 incr num_of_restart_
76 $self send_service_request
77 $self start_service_request_announcement
78
79 # Somebody is serving me, but I did not received any
80 # served message for a while now. So I am just going
81 # to forget it and request a new service.. but first,
82 # stop my current service.
83
84 $self stop_service
85 }
86
87
88 AGLP/Client public send_service_request {} {
89 $self debug "++ send request"
90 $self send "request_service [pid] [gettimeofday]"
91 }
92
93
94 AGLP/Client public send_served_by { gateway_addr } {
95 $self instvar ctrl_port_ pid_
96 $self debug "++ send served_by $gateway_addr $pid_"
97 $self send "served_by $pid_ $gateway_addr [gettimeofday]"
98 }
99
100
101 AGLP/Client public stop {} {
102 $self instvar being_served_timer_
103
104 $self debug "++ stop"
105 if {[$self in_service]} {
106 $self stop_service
107 } else {
108 $self stop_service_request_announcement
109 }
110 $self set running_ 0
111 }
112
113 AGLP/Client public start_service { gateway_addr ctrl_port recv_session_spec } {
114 $self instvar my_gateway_ config_ tcp_channel_ prog_filename_ ctrl_port_
115 $self instvar pid_ application_
116
117 if ![info exists my_gateway_] {
118 set my_gateway_ [new MashSoftState $gateway_addr \
119 $config_(FORGET_BEING_SERVED_PERIOD) \
120 "$self start_service_request_timer"]
121 } else {
122 $my_gateway_ set_value $gateway_addr
123 }
124
125 # LOGGING
126 $self instvar handoff_log_
127 puts $handoff_log_ "[$self time] [lookup_host_name $gateway_addr]"
128 flush $handoff_log_
129
130 # UI
131 # Display host address in the UI
132 global current_gateway
133 set current_gateway [lookup_host_name $gateway_addr]
134
135 set ctrl_port_ $ctrl_port
136
137 $self debug "++ start being served by $gateway_addr"
138
139 $tcp_channel_ open $gateway_addr $ctrl_port
140 set f [open $prog_filename_ r]
141 set announcement_ [$self parse_degas_program $f]
142 $tcp_channel_ send "deglet $pid_ $recv_session_spec $announcement_\n"
143 $self stop_served_by_announcement
144 $self start_served_by_announcement $gateway_addr
145 $self stop_service_request_announcement
146
147 $application_ start_service $recv_session_spec
148 }
149
150 AGLP/Client public stop_service { } {
151 $self instvar my_gateway_ application_ tcp_channel_
152
153 if {[info exists my_gateway_]} {
154 delete $my_gateway_
155 unset my_gateway_
156 }
157 # UI :
158 global current_gateway
159 set current_gateway "none"
160
161 $tcp_channel_ close
162
163 $self stop_served_by_announcement
164 }
165
166 AGLP/Client instproc recv { addr port msg length } {
167
168 $self instvar addr_ application_
169 $self instvar duplicate_counter_
170
171 set magic_word [lindex $msg 0]
172 if {$magic_word != "DCP"} {
173 return
174 }
175 set from [lindex $msg 1]
176 set type [lindex $msg 2]
177
178 if {$from == "client" || $from == "c"} {
179
180 } elseif {$from == "gateway" || $from == "g"} {
181
182 set gateway_addr $addr
183 set client_addr [lindex $msg 3]
184 set pid [lindex $msg 4]
185
186 switch $type {
187 offer_service {
188 set ctrl_port [lindex $msg 5]
189 if {$client_addr == $addr_ && $pid == [pid]} {
190 if {![$self in_service]} {
191 set recv_session_spec [$self get_option outSession]
192 if {$recv_session_spec == ""} {
193 set recv_session_spec [$self generate_new_session_spec]
194 }
195 puts "NEW SESSION $recv_session_spec"
196 $self start_service $gateway_addr $ctrl_port $recv_session_spec
197 } else {
198 $self instvar num_of_restart_
199 incr duplicate_counter_
200 $self debug "recv $duplicate_counter_ -th duplicate offer from $gateway_addr"
201 }
202 }
203 }
204 serve {
205 $self instvar my_gateway_
206 if {$client_addr == $addr_} {
207 if {[info exists my_gateway_]} {
208 if {$gateway_addr == [$my_gateway_ get_value]} {
209 $my_gateway_ refresh
210 }
211 }
212 }
213 }
214 handoff_complete {
215 $self instvar my_gateway_
216 set curr_gateway [lindex $msg 6]
217 if {$client_addr == $addr_ && $curr_gateway == [$my_gateway_ get_value]} {
218 # The client switch the gateway if the followings are true :
219 # - this message is addressed to me
220 #------ LOG -------
221 #global gstats_
222 #incr gstats_(MIGRATION_COUNT)
223 #------------------
224 # - the current gateway is my gateway,
225 set recv_session_spec [lindex $msg 5]
226 set ctrl_port [lindex $msg 7]
227 $self debug "++ Gateway : [$my_gateway_ get_value] -> $gateway_addr"
228 $self stop_service
229 $self start_service $gateway_addr $ctrl_port $recv_session_spec
230 }
231 }
232 replace {
233 # None of my business ?
234 }
235 default {
236
237 }
238 }
239 } else {
240 puts "ERROR : unknown from \"$from\""
241 }
242 }
243
244 AGLP/Client public start_served_by_announcement { gateway_addr } {
245 $self instvar announce_service_timer_ config_
246 $self send_served_by $gateway_addr
247 set announce_service_timer_ [new MashTimer "random_periodic" \
248 $config_(ANNOUNCE_SERVICE_PERIOD) \
249 "$self send_served_by $gateway_addr"]
250 }
251
252
253 AGLP/Client public stop_served_by_announcement { } {
254 $self instvar announce_service_timer_
255 if {[info exists announce_service_timer_]} {
256 $announce_service_timer_ cancel
257 delete $announce_service_timer_
258 unset announce_service_timer_
259 }
260 }
261
262
263 AGLP/Client public start_service_request_announcement { } {
264 $self instvar service_request_timer_ config_
265 set service_request_timer_ [new MashTimer "periodic" \
266 $config_(SERVICE_REQUEST_PERIOD) \
267 "$self send_service_request"]
268 }
269
270
271 AGLP/Client public stop_service_request_announcement { } {
272 $self instvar service_request_timer_
273 if {[info exists service_request_timer_]} {
274 puts "stop service request announcement"
275 delete $service_request_timer_
276 unset service_request_timer_
277 }
278 }
279
280 #------------------------------------------------------------------
281 # AnnounceListenManager/DegasClient::parse_degas_program
282 #
283 # purpose : parse the degas program given the file. this function
284 # basically remove the comments and add the header for
285 # announcement.
286 # input : file - the file that contains the program
287 # output : a list of strings that represents the content of the
288 # program.
289 #------------------------------------------------------------------
290
291 AGLP/Client private parse_degas_program {f} {
292 $self instvar pid_
293 set result ""
294 while {![eof $f]} {
295 set line [gets $f]
296 if {![regexp {^[\ \t]*#.*} $line]} {
297 append result "$line :: "
298 } else {
299 }
300 }
301 return $result
302 }
303
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.