Simon Trudeau wrote:
> Now I think that I understand what you mean! :.)
>
> **********
> ctx.setKeyRegistrationState(Context.KeyRegistrationState.NONE);
>
> // Store those values somewhere:
> SelectionKey key = ctx.getSelectionKey();
> Selectorhandler sl = ctx.getSelectorHandler();
> **********
>
>
> In your explanation, the above make sense, but
>
>
> **********
> Once you have flushed the response,
> just do:
>
> sl.getSelectionKeyHandler().register(key);
>
> So you can get other requests that are coming.
> **********
>
> Cannot work since I register my key only after I have processed (during
> a long time) the received packet, I won't be able to receive and queue
> packets while I am processing! I need to keep the key (or a new key
> maybe?) registered at all time so I can get all packets while my
> application is processing.
I see. Then you need some caching/buffering mechanism and store the read
bytes. My solution doesn't stand :-)
>
> It means that I might be receiving 5 requests but during that time I
> might only be able to process 2!
Right
>
> So How should I set (maybe save) my selectionKey so I can reply to a
> request even after many other requests have arrived and have been queued
> (at the application level)?
You can't save the SelectionKey, but instead you might want to use the
ThreadAttachment and attach your ByteBuffer to it. Grizzly will re-use
that ByteBuffer every time bytes are read. Once you have all your bytes,
you just need to send the response. Take a look at the proposal I did
(now implemented):
http://www.nabble.com/-Proposal---vote--Adding-a-new-ThreadAttachment-fro-partial-read-state-implementation-td11254764.html#a11254764
>
> Also, is there one new Context object per packet received or is that
> object shared among many packets (I know it can be shared when handling
> truncated messages but are there other cases?).
One per packet received.
A+...pogne dans la neige a Montreal :-)
-- jeanfrancois
>
> Thanks,
>
>
> Simon
>
> -----Original Message-----
> From: Jeanfrancois.Arcand_at_Sun.COM [mailto:Jeanfrancois.Arcand_at_Sun.COM]
> Sent: March-07-08 2:30 PM
> To: users_at_grizzly.dev.java.net
> Subject: Re: [Q] Adding delays to protocol filter
>
> Hi Simon,
>
> Simon Trudeau wrote:
>> I want to test the performance of my application. To do so, I intend
> on
>> building an Echo server with delay. Basically, once my request reaches
>
>> my server, I want to delay (simulate response processing) the sending
> of
>> a response. My first guess is to wrap the content of the execute
> method
>> of the EchoFilter inside a callable and have it executed by a
> scheduled
>> executor. Is that thread safe?
>
> Yes you can, but make sure you call:
>
>
> ctx.setKeyRegistrationState(
> Context.KeyRegistrationState.NONE);
>
> // Store those values somewhere:
> SelectionKey key = ctx.getSelectionKey();
> Selectorhandler sl = ctx.getSelectorHandler();
>
>
> inside you Filter, because if not, the key will be registered back and
> it will gives unexpected result. Once you have flushed the response,
> just do:
>
>
> sl.getSelectionKeyHandler().register(key);
>
> So you can get other requests that are coming.
>
>
>
>>
>>
>> What happens to the context object if another packet arrives from the
>> same connection while my server is waiting to send back the response?
>>
>>
>>
>> The issue I want to simulate is a fast producer (client), slow
> consumer
>> (server).
>
> Right. Try the above :-)
>
> Thanks
>
> -- Jeanfrancois
>
>
>>
>>
>> Can I just wrap
>>
>>
>>
>> *public* *boolean* execute(Context ctx) *throws* IOException {
>>
>> *final* WorkerThread workerThread =
>> ((WorkerThread)Thread./currentThread/());
>>
>> ByteBuffer buffer = workerThread.getByteBuffer();
>>
>> buffer.flip();
>>
>> *if* (buffer.hasRemaining()) {
>>
>> // Depending on protocol perform echo
>>
>> SelectableChannel channel =
> ctx.getSelectionKey().channel();
>> *try* {
>>
>> *if* (ctx.getProtocol() == Controller.Protocol./TCP/)
> {
>> // TCP case
>>
>> OutputWriter./flushChannel/(channel, buffer);
>>
>> } *else* *if* (ctx.getProtocol() ==
>> Controller.Protocol./UDP/) { // UDP case
>>
>> DatagramChannel datagramChannel =
> (DatagramChannel)
>> channel;
>>
>> SocketAddress address = (SocketAddress)
>>
>>
>> ctx.getAttribute(ReadFilter./UDP_SOCKETADDRESS/);
>>
>> OutputWriter./flushChannel/(datagramChannel,
>> address, buffer);
>>
>> }
>>
>> } *catch* (IOException ex) {
>>
>> // Store incoming data in byte[]
>>
>> *byte*[] data = *new* *byte*[buffer.remaining()];
>>
>> *int* position = buffer.position();
>>
>> buffer.get(data);
>>
>> buffer.position(position);
>>
>>
>>
>> Controller./logger/().log(Level./WARNING/,
>>
>> "Exception. Echo \"" + *new* String(data) +
> "\"");
>> *throw* ex;
>>
>> }
>>
>> }
>>
>>
>>
>> buffer.clear();
>>
>> *return* *false*;
>>
>> }
>>
>>
>>
>> Inside a callable and execute it from a Schedule Executor or are there
>
>> states that will be messed up (the context maybe...?). What do you
> think?
>>
>>
>> Thanks,
>>
>>
>>
>> Simon
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>