nns_auto.tcl

Go to the documentation of this file.
00001 /*  -*- tcl -*-*/
00002 /*  ### ### ### ######### ######### #########*/
00003 /*  Name Service - Client side connection monitor*/
00004 
00005 /*  ### ### ### ######### ######### #########*/
00006 /*  Requirements*/
00007 
00008 package require nameserv ; /*  Name service client-side core*/
00009 package require uevent   ; /*  Watch for connection-loss*/
00010 
00011 namespace ::nameserv::auto {}
00012 
00013 /*  ### ### ### ######### ######### #########*/
00014 /*  API: Write, Read, Search*/
00015 
00016 /*  TODO - Keep after handle, ensure that only one poll is running.*/
00017 /*  Factor into smaller commands with descriptive names ... We have*/
00018 /*  several near-replicated pieces of code (error handling).*/
00019 
00020 ret  ::nameserv::auto::bind (type name , type data) {
00021     # See nameserv::bind. Remembers the information, for re-binding
00022     # when the connection was lost, and later restored.
00023 
00024     variable bindings
00025     variable delay
00026 
00027     # Watch base client for loss of connection.
00028     uevent::bind nameserv lost-connection ::nameserv::auto::Reconnect
00029 
00030     if {[catch {
00031     nameserv::bind $name $data
00032     } msg]} {
00033     if {[string match *No name server*]} {
00034         # No nameserver. Remember, and start reconnect polling.
00035         set bindings($name) $data
00036         after $delay ::nameserv::auto::Reconnect
00037         return
00038     }
00039     # Name is bound already, lost immediately, generate
00040     # standard event.
00041 
00042     uevent::generate nameserv lost-name [list name $name data $data]
00043     return
00044     }
00045 
00046     # Success. Remember for possible loss of connection.
00047     set bindings($name) $data
00048     return
00049 }
00050 
00051 ret  ::nameserv::auto::Reconnect (type args) {
00052     # args = <>|<tags event details>
00053     # <tag,event> = <'nameserv','lost'>
00054     #     details = dict ('reason' -> string)
00055 
00056     if {![catch {
00057     ::nameserv::server_features
00058     }]} {Rebind ; return}
00059 
00060     variable delay
00061     after   $delay ::nameserv::auto::Reconnect
00062     return
00063 }
00064 
00065 ret  ::nameserv::auto::Rebind () {
00066     variable bindings
00067 
00068     foreach {name data} [array get bindings] {
00069     if {[catch {
00070         nameserv::bind $name $data
00071     } msg]} {
00072         # Lost server while rebinding names. Abort and wait for
00073         # the reconnect to try again.
00074         if {[string match *No name server*]} break
00075 
00076         # Other error => (name already bound) That means someone
00077         # else took the name while we were not connected to the
00078         # service. Best effort we can do: Deliver total loss of
00079         # this binding to observers via event.
00080 
00081         uevent::generate nameserv lost-name [list name $name data $data]
00082     }
00083     }
00084     return
00085 }
00086 
00087 /*  ### ### ### ######### ######### #########*/
00088 /*  Initialization - System state*/
00089 
00090 namespace ::nameserv::auto {
00091     /*  In-memory database of bindings to restore after connection was*/
00092     /*  lost and restored.*/
00093 
00094     variable bindings ; array  bindings =  {}
00095 }
00096 
00097 /*  ### ### ### ######### ######### #########*/
00098 /*  API: Configuration management (host, port)*/
00099 
00100 ret  ::nameserv::auto::cget (type option) {
00101     return [configure $option]
00102 }
00103 
00104 ret  ::nameserv::auto::configure (type args) {
00105     variable delay
00106 
00107     if {![llength $args]} {
00108     return [list -delay $delay]
00109     }
00110     if {[llength $args] == 1} {
00111     # cget
00112     set opt [lindex $args 0]
00113     switch -exact -- $opt {
00114         -delay { return $delay }
00115         default {
00116         return -code error "bad option \"$opt\", expected -delay"
00117         }
00118     }
00119     }
00120 
00121     while {[llength $args]} {
00122     set opt [lindex $args 0]
00123     switch -exact -- $opt {
00124         -delay {
00125         if {[llength $args] % 2 == 1} {
00126             return -code error "value for \"$opt\" is missing"
00127         }
00128         # TODO: check integer > 0
00129         set delay [lindex $args 1]
00130         set args  [lrange $args 2 end]
00131         }
00132         default {
00133         return -code error "bad option \"$opt\", expected -delay"
00134         }
00135     }
00136     }
00137     return
00138 }
00139 
00140 /*  ### ### ### ######### ######### #########*/
00141 /*  Initialization - Tracing, Configuration*/
00142 
00143 logger::initNamespace ::nameserv::auto
00144 namespace        ::nameserv::auto {
00145     /*  Interval between reconnection attempts when connection was lost.*/
00146 
00147     variable delay 1000 ; /*  One second*/
00148 }
00149 
00150 /*  ### ### ### ######### ######### #########*/
00151 /*  Ready*/
00152 
00153 package provide nameserv::auto 0.1
00154 
00155 /** 
00156  * ### ### ### ######### ######### #########
00157 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1