“You cannot teach a man anything, ..” — Galileo
You must go and play with
tcpip_connection_stream and see for yourself. So that is what I did. The result is a module and exemplar called “daemon”, available on my github page. I think it can be used to build network services with Smallworld and I’ll show you how.
daemon main loop is as follows:
1 2 3 4 5 6 7
A listening socket can be made in Smallworld with
.get() on it waits for and accepts connections.
.get() returns an accepted socket, which is of type
tcpip_connection in magik. That connection is best handled in a new thread, because the listening thread should quickly return to accept new connections. This logic is in the run method on my “daemon” exemplar. Client connections are handled as outlined in the following lines:
1 2 3 4 5 6 7
To understand above lines, you need to know how to register services in my network service shell. They are simply put in the global
daemon.services like so (yes indeed, no xml configuration):
This means a service can be anything that understands the
invoke() protocol. This includes procs. The following block of code implements a service that lists system themes in the Electricity ACE of the Cambridge Database:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
Before or after registering the service call
daemon.run() to start my network shell. A client for the
list_system_themes service can be found in this gist.
To sum up, each TCP/IP connection is handled in a separate thread and there are no explicitly engineered bounds on the number of threads created. Taking into consideration that the Magik VM on 4.3 is single-threaded, there appears to be no point in having many cuncurrent client connections. In light of the outstanding service provided by one Magik VM I would not place the network shell in a heavy-use multi user environment without a facade, and the use of a proxy that serialises requests seems the architecture of choice.