August 5, 2012 at 7:56 pm #736
Currently, the way to use SocketServer is to implement a class that inherits from SocketServer and defines a Run method. This works well, but there is a limitation.
SocketServer creates an instance of your class for each incoming socket connection. But since it is creating the instances, there is no way to pass arguments. This means there is no way to get dynamic runtime information into a SocketServer.
The improvement is to allow passing extra arguments to SocketServer (in addition to the current name, port, and exit).
My first thought was to pass the arguments each time a new instance was created for an incoming connection. But that seemed both wasteful, and not intuitive, since you expect New to be called only once.
Instead, when you call SocketServer it now creates a “master” instance, passing the arguments to New. Then for each incoming connection it duplicates this master instance, without calling New again.
When it passes the arguments to New, it ensures that the SocketServer’s arguments (name, port, exit) are named. For example:
MySocketServer(“myname”, 9000, false, “extra argument”, another: 123)
New(“extra argument”, another: 123, name: “myname”, port: 9000, exit: false)
So the SocketServer’s arguments (name, port, exit) are available if you want them. But since they are named you do not have to receive them. For example, your New could be either of:
New(extra, another) or New(extra, another, name, port, exit)
Note: If you do receive them, they have to be the same names (name, port, exit).
This change is backwards compatible, existing SocketServer code will continue to work as before.
With this change, for example, HttpServer could now take the routing as an argument instead of being hard coded to use HttpMap. Then you could run multiple servers without having to define different classes. Or you could load the routing from a configuration file.
One thing to watch out for, is that when the master instance is duplicated, this is a “shallow” copy. So if you pass in an object, each instance will reference the same object. So if one instance modifies the object, this change will affect all instances. And since each connection instance is running in it’s own fiber, shared mutable data could also mean concurrency issues. Less so on cSuneido because fibers share a single thread, more so on jSuneido where it uses real threads.
I’ve implemented this on cSuneido and jSuneido – the source code is in version control on SourceForge.
You must be logged in to reply to this topic.