Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

tcllib tie package issue with remotearray datasource

5 views
Skip to first unread message

Bezoar

unread,
May 9, 2007, 12:41:31 PM5/9/07
to

A previous post wanted an easy way to update an array to/from a server
process to any other process that was listening so I automatically
thought of using the tcllib tie library as it had a remotearray data
source. I created a server to hold the remote array, an interactive
client that can change the values on the server, and a client that
does nothing but display changes made to the remote array on the
server. (Code below) However it does not work as advertised. The man
page for tie says:

"...Just tie several Tcl arrays in many client processes to a Tcl
array in a server and all changes to any of them will be distributed
to all."

The only way I could get it so the reader process was updated was to
re-establish the link via a new tie in a timed while loop. Debug
messges show the number of ties building ( as you would expect) but
tie ( on server ) does not iterate through them as it should. I'd
rather use a trace to detect changes as it allows other activities to
happen. What am I doing wrong or does the "remotearray" tie not
support what was advertised?

######## Server #####################
#!/opt/usr/bin/tclsh8.5
package require tie
global av forever
array set av ""
set forever 0
set port [ lindex $argv 0 ]
package require comm;
::comm::comm config -port $port -listen 1
::comm::comm debug 1
vwait forever
::comm::comm abort
exit 0
############ END #####################
######### Updater ###################
#!/opt/usr/bin/tclsh8.5
package require tie
global av forever
array set av ""
set forever 0
set port [ lindex $argv 0 ]
package require comm
tie::tie av -open remotearray av {comm::comm send} $port
puts "initial array"
set done 0
while { !$done } {
parray av
puts -nonewline stdout "Enter key or q to quit: "
flush stdout
gets stdin key
if { [string equal $key "q" ] } {
break;
}
set key [string trim $key]
puts -nonewline stdout "Enter value:"
flush stdout
gets stdin value
#update the remote array
if { [ catch { set av($key) \"$value\" } err ] != 0 } {
puts "$err"
}
}
############ END #####################
########### READER ###################
#!/opt/usr/bin/tclsh8.5
package require tie

proc arrayChanged { name index op } {
global av forever
upvar $name myArray
puts " $name\($index\) was $op"
switch -exact -- $op {
"read" {
;
}
"write" {
puts "array Changed"
parray myArray
}
"unset" {
puts "array removed"
puts "exiting..."
set forever 1
}
}

}
global av forever
array set av ""
set forever 0

set port [ lindex $argv 0 ]
package require comm
tie::tie av -open remotearray av {comm::comm send} $port
puts "initial array"
parray av
#what works but while loop not optimal
while { 1 } {
after 1000;
# this is necessary to get a refresh wont work without
tie::tie av -open remotearray av {comm::comm send} $port
parray av
}
# what I want to work
trace add variable av {read write unset } arrayChanged
vwait forever
::comm::comm abort
exit 0
########### End Reader #####################

To run open three or more terminals
in one run the server:

server.tcl <port>

in another run the updater:

updater.tcl <port>

in as many other terminals as you want run

reader.tcl <port>

use the updater to add key value pairs to the remote array
check behavior in reader window.

Thanks ahead of time

Carl

0 new messages