On 2-4-2017 17:35, Vlad Khorsun wrote:
> 02.04.2017 18:07, Mark Rotteveel wrote:
>> On 2-4-2017 16:48, Vlad Khorsun wrote:
> ...
>>>    So, we have following packets exchange
>>>
>>> 1. op_que_event TEST_EVENT_A, cnt = 0xF5 (245), id = 0xD4 (212)
>>> 2. op_event     TEST_EVENT_B, cnt = 0x7C (124), id = 0xD3 (211)
>>> 3. op_que_event TEST_EVENT_B, cnt = 0x7C (124), id = 0xD5 (213)
>>> 4. op_event     TEST_EVENT_A, cnt = 0xF7 (247), id = 0xD5 (213)
>>> 5. op_que_event TEST_EVENT_B, cnt = 0xF7 (247), id = 0xD6 (214)
>>> 6. op_event     TEST_EVENT_B, cnt = 0x7D (125), id = 0xD5 (213)
>>>
>>>    Packet 4 should contain id 212, agree. Looks like a server bug.
>>>
>>>    But how could you explain packet 5 which contains wrong count (247) ?
>>> op_que_event packet is created by client, it should not be affected by
>>> any server bug.
>>
>> That is because the current implementation in Jaybird only looks at the
>> id, so when in step 4 it receives id 213 with count 247, it assumes that
>> 247 is the new count for TEST_EVENT_B. It then re-queues that event with
>> the updated count.
>>
>> This BTW is also what I believe the native implementation does: only
>> looking at the id.
>
>    Not sure i understand it. Does it means that events buffer, used at packet 
> 4,
> was reused to reque same event at packet 5 ? If yes, why event name was 
> changed
> by client while events count - doesn't ? If client looked at id when received
> event and re-queued it again - why it changed event name ? I could understand
> if client, when re-queued same event, leave received buffer as is...

No, that is not how Jaybird works.

* It received an event for id 213 with count 247. Internally it notifies 
a listener of that (V10AsynchronousChannel.processSingleEvent)

* That listener will notify all 'event handles' 
(AsynchronousChannelListenerDispatcher.eventReceived)

* The one with a matching event id (TEST_EVENT_B in this case) updates 
its internal count (WireEventHandle.eventReceived)

* That in turn will cause the event handler to be notified, in this case 
that will calculate the change between previous and current count and 
post an update to an internal queue for asynchronous notification of 
interested parties (FBEventManager.GdsEventHandler.eventOccurred)

* The handler of the previous step will then re-queue the event

The queueing of events is done by writing into a socket stream, it 
doesn't reuse buffers for that. See 
https://github.com/FirebirdSQL/jaybird/blob/master/src/main/org/firebirdsql/gds/ng/wire/version10/V10AsynchronousChannel.java#L192

>    Also, i thought that test is multy threaded. Now it looks like sample above
> was produced by single thread, correct ?

Depends on what you want to be single or multi-threaded. The inserts 
that cause events to be posted are done on multiple threads (5 threads x 
100 inserts).

The receiving of event notifications and re-queuing is a single thread 
handled by AsynchronousProcessor (speaking about the wire protocol 
implementation only).

>    Asking all that questions i want to be sure that there is no mistake at 
> client
> side when working with event buffers.

The only buffer that is reused is the ByteBuffer for reading the 
received events from the socket channel, that buffer is automatically 
restricted to the number of bytes actually read, it is not possible to 
read beyond that and for example read stale data from a previous read.

>    As for what "native implementation does" - fbclient does nothing whith 
> events
> buffers, it just passed it between application and the server.

Then how does the native client identify the correct callback handle to 
invoke?

Mark
-- 
Mark Rotteveel

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to