for a TCL project I need a kind of TCL daemon. It should work in the
following matter:
- it can be started with a script "startup.tcl", that opens some file
handles and sets a lot of global variables
- now it should be callable with several tcl-scripts and should always
keep in mind all the globals from the startup-script
- it can be shut down with "shutdown.tcl"
So the main idea for me is to avoid calling startup and shutdown
everytime I call a service, so I do not want something like
source ./startup.tcl
source ./service.tcl
source ./shutdown.tcl
for every source like service.tcl. Instead, I am looking for something like
source ./startup.tcl
# now beeing ready to receive several scripts like ./service1.tcl,
# ./service2.tcl and so on, using the globals specified
# in ./startup.tcl
# shutting down when shutdown.tcl is called
Does anybody have an idea how to realize this structure?
Thanks a lot,
Martin
What you could do is this:
Run the startup script and have it dump its global variables to a
small file that you read when running the services.
That means you only have to compute the global variables once.
If they are constant, then you could simply put them in a source file
and source that at the start of the service.
But perhaps I should ask some questions first:
- How would you communicate with this daemon?
A simple solution: You could simply have an interactive tclsh shell
that first sources the startup script and then reads your commands
- Do these global variables have fixed values or not?
Regards,
Arjen
> What you could do is this:
>
> Run the startup script and have it dump its global variables to a
> small file that you read when running the services.
In my opinion, that would be at least the same complexity than declaring
these variables directly in an own script (as it is realized now).
> That means you only have to compute the global variables once.
It is no real computation complexity, since most variables are only
declared, and some associative arrays are generated from csv-Files. Both
reading csv files or the suggested small file I would like to avoid if
that is possible.
> But perhaps I should ask some questions first:
> - How would you communicate with this daemon?
That's a major question.. I really do not know all the possibilities.
Later in my project, I perhaps could use a tcl-webserver (?), but for
now, I'd like to keep things simple.
> A simple solution: You could simply have an interactive tclsh shell
> that first sources the startup script and then reads your commands
Yes, that's exactly what I´m looking for (for now). Could You give me a
short hint or link how to realize such a shell event driven?
> - Do these global variables have fixed values or not?
They may only change if the parsed csv files change. In this case, I
would run the shutdown and startup scripts.
Thanks
Martin
At start-up tclsh will read a file .tclshrc from the user's home
directory.
That is one way of doing it. Then you would simply have a shell
waiting
for commands.
Another possibility is:
source startup.tcl
set prev_time [clock seconds]
while {1} {
set mtime [file mtime services.tcl]
if { $mtime > $prev_time } {
set prev_time $mtime
source services.tcl
}
if { [file exists shutdown.tcl] } {
source shutdown.tcl
exit
}
after 1000
}
This little sketchy program would source the startup script first and
enter an endless loop in which it looks for two files in the current
directory:
- a file containing the service commands you want to run
- a file to shut it down
The criterion is very simple - either the file exists or it is newer
than some
previous file. Starting the services then means that you copy a new
file
into the directory.
This scenario can be expanded at will.
Regards,
Arjen
> Another possibility is:
>
> source startup.tcl
>
> set prev_time [clock seconds]
> while {1} {
> set mtime [file mtime services.tcl]
> if { $mtime > $prev_time } {
> set prev_time $mtime
> source services.tcl
> }
> if { [file exists shutdown.tcl] } {
> source shutdown.tcl
> exit
> }
> after 1000
> }
> This little sketchy program would source the startup script first and
> enter an endless loop in which it looks for two files in the current
> directory:
> - a file containing the service commands you want to run
> - a file to shut it down
Thank's, that seems to be very close to the solution I'm looking for.
Although I see the problem that this solution is not even-driven, so two
fast file changes of services.tcl would eventually not be recognized and
only lead to the execution of the later version of services.tcl.
Regards
Martin
You could use the comm extension from tcllib to send scripts to the
daemon to be [eval]'ed.
-- Neil
Thanks for the idea, I will have a look at the docs. Is there something
more intuitive (with some short examples) than
http://tcllib.sourceforge.net/doc/comm.html?
Regards
Martin
There is http://wiki.tcl.tk/comm, but most of the code seems concerned
with emulating Tk's send. Essentially, in your daemon code you'd do:
package require comm
set out [open comm_id.tcl w]
puts $out "set comm_id [comm::comm self]"
close $out
vwait forever ;# start event loop
and then in the job scripts you'd do:
package require comm
source comm_id.tcl ;# get id of daemon
comm::comm send $comm_id [list source myjob.tcl]
Of course, you may want to consider security implications etc.
-- Neil
A Tcl-webserver can be simple. Look at DustMote: http://wiki.tcl.tk/4333
and DustMotePlus: http://wiki.tcl.tk/16867 for great examples of how
much power can reside in a few lines of code.
Gerry
That sound's actually simple..
And in the deamons code, I could call "source startup.tcl", so that the
scripts which are sent to the daemon could use the declared variables of
startup.tcl?
Thanks,
Martin
Yes, the code you send to the daemon process are run within its
interpreter, so all variables are available.
Of course, as Neil mentions, you will probably need to consider some
security issues
Regards,
Arjen