1# $Id$ 2 3package require ctable_client 4package require st_client 5 6namespace eval ::stapi { 7 # shared://port/[dir/]table[/stuff][?stuff] 8 # options: 9 # -build dir 10 # Specify path to ctable build directory 11 # 12 variable shared_serial 0 13 variable shared_build_dir "" 14 15 proc connect_shared {table_path {address ""} args} { 16 variable shared_serial 17 variable shared_build_dir 18 19 if {[info exists shared_build_dir] && "$shared_build_dir" != ""} { 20 set opts(-build) $shared_build_dir 21 } 22 23 array set opts $args 24 25 if {"$address" == ""} { 26 set host localhost 27 set port "" 28 } elseif {![regexp {^(.*):(.*)$} $address _ host port]} { 29 set host localhost 30 set port $address 31 } 32 33 if {"$host" != "localhost" && "$host" != "127.0.0.1"} { 34 return -code error "Can not make a shared connection to a remote server" 35 } 36 37 if {"$port" == ""} { 38 set address $host 39 } else { 40 set address $host:$port 41 } 42 43 set uri ctable://$address/$table_path 44 45 set ns ::stapi::shared[incr shared_serial] 46 47 # insert handler proc (below) into namespace, and create the namespace 48 namespace eval $ns [list proc handler {args} [info body shared_handler]] 49 50 remote_ctable $uri ${ns}::master 51 set handle [${ns}::master attach [pid]] 52 array set prop [${ns}::master getprop] 53 54 if {[info exist opts(-build)]} { 55 if {[lsearch $::auto_path $opts(-build)] == -1} { 56 lappend ::auto_path $opts(-build) 57 } 58 } 59 60 namespace eval :: [list package require [string totitle $prop(extension)]] 61 $prop(type) create ${ns}::reader reader $handle 62 63 # Everything's been successfully completed, remember that in the created 64 # namespace. 65 set ${ns}::handle $handle 66 set ${ns}::table $prop(type) 67 set ${ns}::attached 1 68 return ${ns}::handler 69 } 70 register shared connect_shared 71 72 # Simple handler, most commands are passed straight to the master. 73 # 74 # Note cheesy object model! 75 # 76 # This executes in the stapi::sharedN namespace created in connect_shared, 77 # never in this namespace, so references to "reader" and "master" are 78 # the two stapi objects created there. 79 proc shared_handler {args} { 80 set method [lindex $args 0] 81 variable attached 82 switch -glob -- [lindex $args 0] { 83 search* { 84 #puts "\nrunning shared_handler search, '[namespace which reader] $args'" 85 catch {uplevel 1 [namespace which reader] $args} catchResult catchOptions 86 87 #puts "shared_handler search ran, args '$args' result '$catchResult', options $catchOptions\n" 88 dict incr catchOptions -level 1 89 return -options $catchOptions $catchResult 90 } 91 destroy { 92 if {$attached} { 93 master destroy 94 } 95 reader destroy 96 } 97 detach { 98 if {$attached} { 99 master destroy 100 set attached 0 101 } 102 } 103 default { 104 if {$attached} { 105 #puts "\nrunning shared_handler default case, args '$args'" 106 catch {uplevel 1 [namespace which master] $args} catchResult catchOptions 107 #puts "shared_handler default case ran, args '$args' result '$catchResult', options $catchOptions\n" 108 dict incr catchOptions -level 1 109 return -options $catchOptions $catchResult 110 } else { 111 return -code error "Detached shared table can only 'search' and 'destroy'" 112 } 113 } 114 } 115 } 116} 117 118package provide st_shared 1.13.12 119 120# vim: set ts=8 sw=4 sts=4 noet : 121