My head just visited another idea, and i'd like to share it :)
There was a discussion on how to pass sockets between images safely. And due to reasons that it's not safe, not easy, and require a lot changes which may break compatibility, solution was postponed for a future. Now, i think i found the way how to pass the newly created socket to another image by using a special accept primitive. What this primitive should do: by taking parameters: interpreter handle, socket handle and channel name, it should 1. do validity checks (all handles should be valid e.t.c) 2. accept new incoming socket connection (socket handle passed to primitive should be in listen mode) 3. if system fails with accept(), primitive fails 4. create an event and put new socket handle , and channel name to it. 5. enqueue given event to target interpreter event queue. -- Event handling: - register socket handle in SocketPlugin internal structures. - then find channel with given name, and put SocketHandle bytearray as packet. voila.. Now at language side, you simply need a channel, which listening for packets, containing socket handles. Once packet received, you know, that it's newly accepted socket connection and can do anything you want with it. ............ by finishing writing this, i just thought that passing ownership of already open socket can be done in similar way: a primitive can remove given socket from SocketPlugin internal structures and pass it with event to another interpreter. -- Best regards, Igor Stasenko AKA sig. |
On Tue, 26 Feb 2008 04:51:56 +0100, Igor Stasenko wrote:
> My head just visited another idea, and i'd like to share it :) > > There was a discussion on how to pass sockets between images safely. > And due to reasons that it's not safe, not easy, and require a lot > changes which may break compatibility, solution was postponed for a > future. > > Now, i think i found the way how to pass the newly created socket to > another image by using a special accept primitive. > > What this primitive should do: > > by taking parameters: interpreter handle, socket handle and channel > name, it should > 1. do validity checks (all handles should be valid e.t.c) > 2. accept new incoming socket connection (socket handle passed to > primitive should be in listen mode) Does your 2. correspond to the line I marked in the following?: | localhost serverSocket clientSocket sessionSocket listener | localhost := NetNameResolver localHostAddress. serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1. listener := [serverSocket waitForConnectionFor: 0.5 ifTimedOut: [Transcript cr; show: 'timed out ', serverSocket statusString]] forkAt: Processor activeProcess priority. clientSocket := Socket newTCP connectTo: localhost port: 7680. (Delay forMilliseconds: 250) wait. "marked" sessionSocket := serverSocket accept. Transcript cr; show: '[server] ', serverSocket statusString; cr; show: '[session] ', sessionSocket statusString; cr; show: '[client] ', clientSocket statusString; cr; show: 'listener: ', listener browserPrintString; cr. serverSocket destroy. clientSocket destroy. sessionSocket destroy You mean, the marked line would be done by the new primitive, the accepted Socket then passed to another HydraVM instance (err, interpreter, via channel)?! That would allow "workers" run on their own CPU :) > 3. if system fails with accept(), primitive fails > 4. create an event and put new socket handle , and channel name to it. > 5. enqueue given event to target interpreter event queue. > -- > > Event handling: > - register socket handle in SocketPlugin internal structures. > - then find channel with given name, and put SocketHandle bytearray as > packet. > > voila.. > > Now at language side, you simply need a channel, which listening for > packets, containing socket handles. > Once packet received, you know, that it's newly accepted socket > connection and can do anything you want with it. > > ............ > by finishing writing this, i just thought that passing ownership of > already open socket can be done in similar way: > a primitive can remove given socket from SocketPlugin internal > structures and pass it with event to another interpreter. > |
On 26/02/2008, Klaus D. Witzel <[hidden email]> wrote:
> On Tue, 26 Feb 2008 04:51:56 +0100, Igor Stasenko wrote: > > > My head just visited another idea, and i'd like to share it :) > > > > There was a discussion on how to pass sockets between images safely. > > And due to reasons that it's not safe, not easy, and require a lot > > changes which may break compatibility, solution was postponed for a > > future. > > > > Now, i think i found the way how to pass the newly created socket to > > another image by using a special accept primitive. > > > > What this primitive should do: > > > > by taking parameters: interpreter handle, socket handle and channel > > name, it should > > 1. do validity checks (all handles should be valid e.t.c) > > 2. accept new incoming socket connection (socket handle passed to > > primitive should be in listen mode) > > > Does your 2. correspond to the line I marked in the following?: > > | localhost serverSocket clientSocket sessionSocket listener | > localhost := NetNameResolver localHostAddress. > serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1. > listener := [serverSocket waitForConnectionFor: 0.5 > ifTimedOut: [Transcript cr; show: 'timed out ', > serverSocket statusString]] > forkAt: Processor activeProcess priority. > clientSocket := Socket newTCP connectTo: localhost port: 7680. > (Delay forMilliseconds: 250) wait. > "marked" sessionSocket := serverSocket accept. > Transcript cr; show: '[server] ', serverSocket statusString; > cr; show: '[session] ', sessionSocket statusString; > cr; show: '[client] ', clientSocket statusString; > cr; show: 'listener: ', listener browserPrintString; cr. > serverSocket destroy. > clientSocket destroy. > sessionSocket destroy > > You mean, the marked line would be done by the new primitive, the accepted > Socket then passed to another HydraVM instance (err, interpreter, via > channel)?! That would allow "workers" run on their own CPU :) > Yes, approximately. So, in _another_ image code can look like: HydraChannel listen: #acceptChannel onData: [:socketHandle | | sessionSocket | sessionSocket := Socket fromHandle: socketHandle. "we need to check this, because data can come to channel from random source" sessionSocket isValid ifTrue: [ sessionSocket initSemaphores. "bind new semaphores (read/write/close)" [ MyClass startSessionWith: sessionSocket ] fork. " now we can work with socket" ] ] And at 'dispatcher' side, where you having server socket listening for connections, it can look like: interpreter := self selectWorkerWithMinimalLoad. serverSocket acceptBy: interpreter onChannel: #acceptChannel. Interesting, that squeakers can implement own #selectWorkerWithMinimalLoad by any criteria they want, and distribute threads load by own criteria (assume worker threads passing some feedback to dispatcher thread). This is unlikely can be achieved using multiple OS processes setup. In fact, it's nearly impossible :) -- Best regards, Igor Stasenko AKA sig. |
Free forum by Nabble | Edit this page |