do i need 2nd controller for multiplexing writes?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

do i need 2nd controller for multiplexing writes?

Radim Kolar
i wonder if there is better way to handle writes than making own selector and
doing select() loop in Filter, because it wastes 1 worker thread/client just
for looping around select() and writing output data to client. I think app
should do multiplexed writes and break 1:1 thread/client maping.

i am here:
Selector() OP_READ -> Worker thread -> Protocol filter -> request parsed, reply
is stored into Context

so i need to make 2nd controller because i cant have 2 ProtocolChainInstanceHandlers / controller and i don't think chains like ReaderFilter - something - Write filter works.

Now i need to do ?
1. switch registration of select type on channel from OP_READ to OP_WRITE
2. deregister Selection key from controller/selector
3. assign selection key to different controller

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: do i need 2nd controller for multiplexing writes?

Jeanfrancois Arcand-2


Radim Kolar SF.NET wrote:
> i wonder if there is better way to handle writes than making own selector and
> doing select() loop in Filter, because it wastes 1 worker thread/client just
> for looping around select() and writing output data to client. I think app
> should do multiplexed writes and break 1:1 thread/client maping.

Agree. The temporary Selector trick we use here might not be appropriate
for all case. One way to workaround the problem would consist of having
a decicated SelectorHandler + WriteFilter on which you can register a
ByteBuffer and get notified when the byte are fully written. We have
discussed several time on that list having a Write queue functionality,
we just didn't have a chance yet to implement it.

>
> i am here:
> Selector() OP_READ -> Worker thread -> Protocol filter -> request parsed, reply
> is stored into Context
>
> so i need to make 2nd controller because i cant have 2 ProtocolChainInstanceHandlers / controller and i don't think chains like ReaderFilter - something - Write filter works.

It will work but like you noted, the Write will block if the network is
slow or if the client isn't reading bytes fast enough. But it can work.

>
> Now i need to do ?
> 1. switch registration of select type on channel from OP_READ to OP_WRITE
> 2. deregister Selection key from controller/selector
> 3. assign selection key to different controller

Yes probably. Working on an async write queue is exactly what you need I
suspect. What I was having in mind is to be able, from a Context (using
the getAttribute()), to get a reference to a write queue where you can
register something like that:

    ((WriteQueue)ctx.getAttribute(Grizzly.WriteQueue)).write(new
WriteCallbackHandler(SelectionKey) {

        public void onComplete(...){
         }

         public void onException(...){
        }
});

The WriteQueue will take care or handling the async write.

What do you think? That would make asyn write easy to handle.

Just thinking loud :-)

Thanks

-- Jeanfrancois





>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

async writes via 2 protocol chains on one controller

Radim Kolar
> Yes probably. Working on an async write queue is exactly what you need I
> suspect. What I was having in mind is to be able, from a Context (using the
> getAttribute()), to get a reference to a write queue where you can register
> something like that:
>
>    ((WriteQueue)ctx.getAttribute(Grizzly.WriteQueue)).write(new
> WriteCallbackHandler(SelectionKey) {
>
> public void onComplete(...){
>         }
>
>         public void onException(...){
> }
> });
i think about this scheme:

 Allow multiple protocolchains registration per controller.

 1.
 controller.setProtocolChainInstanceHandler(chain,operation) OP_READ or OP_WRITE
etc..) or some kind of mask OP_READ|OP_WRITE

 2. Use context for passing protocol state between chains
    This needs 1:1 Context vs SelectionKeys mapping. Bind context to SelectionKey

 3. In filter reader chain just alter protocol state in context or write raw data into context write buffer) and switch SelectionKey on Selector from OP_READ to OP_WRITE and return false; (don't call next filter in read chain).
 
 4. in next select() loop
    SelectionKey + Context will arrive into protocol writer chain:

    protocol dependent writer (add headers, check protocol state from context,
    extract data to be written from Context and put result into TLS bytebuffer)
    if no more data to write switch to reader or close connection.
    WriteFilter.java (generic bytes writer, should not close connection after all data are send)

 5.
    consider writing new filter classes.
        EOFFilter() - cancel connection if no more data needs to be sent.
        SwitchToRead() - switch to read mode if no more data needs to be sent.
        SwitchToWrite() ditto

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: async writes via 2 protocol chains on one controller

Jeanfrancois Arcand-2


Radim Kolar SF.NET wrote:

>> Yes probably. Working on an async write queue is exactly what you need I
>> suspect. What I was having in mind is to be able, from a Context (using the
>> getAttribute()), to get a reference to a write queue where you can register
>> something like that:
>>
>>    ((WriteQueue)ctx.getAttribute(Grizzly.WriteQueue)).write(new
>> WriteCallbackHandler(SelectionKey) {
>>
>> public void onComplete(...){
>>         }
>>
>>         public void onException(...){
>> }
>> });
> i think about this scheme:
>
>  Allow multiple protocolchains registration per controller.
>
>  1.
>  controller.setProtocolChainInstanceHandler(chain,operation) OP_READ or OP_WRITE
> etc..) or some kind of mask OP_READ|OP_WRITE

That sound a good idea.

>
>  2. Use context for passing protocol state between chains
>     This needs 1:1 Context vs SelectionKeys mapping. Bind context to SelectionKey

Right now the Context is associated with the SelectionKey. What you
means is doing something like key.attach(context), the register the key
and re-use the Context from that key?

>
>  3. In filter reader chain just alter protocol state in context or write raw data into context write buffer) and switch SelectionKey on Selector from OP_READ to OP_WRITE and return false; (don't call next filter in read chain).

Should this can be done in another filter instead?


>  
>  4. in next select() loop
>     SelectionKey + Context will arrive into protocol writer chain:

Yes.

>
>     protocol dependent writer (add headers, check protocol state from context,
>     extract data to be written from Context and put result into TLS bytebuffer)
>     if no more data to write switch to reader or close connection.
>     WriteFilter.java (generic bytes writer, should not close connection after all data are send)

Agree although I still think the current WriteFilter is not doing that :-)

>
>  5.
>     consider writing new filter classes.
>         EOFFilter() - cancel connection if no more data needs to be sent.
>         SwitchToRead() - switch to read mode if no more data needs to be sent.
>         SwitchToWrite() ditto

:-) Sound good :-) Patches/Contributions are welcome :-)

Thanks

-- Jeanfrancois


>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: async writes via 2 protocol chains on one controller

Radim Kolar
> Right now the Context is associated with the SelectionKey. What you means
> is doing something like key.attach(context), the register the key and
> re-use the Context from that key?
i am not sure, but i think that now every select() loop different context
is fetched from cache attached to SelectionKey, they are not 1:1 mapped.
using key.attach by framework itself of course should be avoided.

>>  3. In filter reader chain just alter protocol state in context or write
>> raw data into context write buffer) and switch SelectionKey on Selector
>> from OP_READ to OP_WRITE and return false; (don't call next filter in read
>> chain).
> Should this can be done in another filter instead?
yes think about coding echo like:
op_read: ReadFilter SwitchToWriteFilter
op_write: WriteFilter SwitchToReadFilter

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]