Implementing new transport to optimize Axis2/C when used in a multi-threading 
client environment.
-------------------------------------------------------------------------------------------------

                 Key: AXIS2C-1328
                 URL: https://issues.apache.org/jira/browse/AXIS2C-1328
             Project: Axis2-C
          Issue Type: Improvement
          Components: core/transport
            Reporter: Damitha Kumarage
            Priority: Minor


I would like to highlight the following discussion in mailing thread[1].

Patric:
The asynchronous call implementation of axis is based on creating new threads 
that just wait on a response. Threads are a rather expensive resource to use 
for just waiting on an IO completion (and then performing some small task). It 
might be better that the waiting on all outstanding IO is done by one single 
thread. The work after the IO completed can then be done by either that thread, 
or a (small and static) thread pool. That way, no threads have to be created / 
deleted on the flow, not more than one thread is waiting on IO and no high 
amount of threads will exist when a lot of asynchronous calls exist in 
parallel. My axis knowledge is not enough to see solutions for this within axis 
right now.

Carl:
My reason for responding though is really to comment on this phrase:"Threads 
are a rather expensive resource to use for just waiting on an IO completion".  
It may be my lack of understanding, but I am pretty
sure that -- at least in the win32 tcp/ip stack -- once your thread goes into 
asynchronous communication on a socket, you do not see it again until there is 
some result.  This means if there is a timeout your
thread is inactive for a long time.  How can one thread wait on more than one 
asychronous communication?  I admit this would be a far better solution, 
however from my understanding of winsock2 it is not possible.

Seen this way, one thread per socket communication is maybe expensive in 
resources, but it is the only way to ensure your main thread continues to 
operate in a timely fashion.

Patric: 
With the fd_set in winsock and the select() function, you can wait at a maximum 
of 64 (current implementation) sockets at once. With I/O Completion Ports you 
can use one thread for an infinite number of ports (though a pool of threads 
might be a good idea if the number of sockets grows large). This is also used 
by the well known boost (C++) library. Mechanisms like these would be a much 
better implementation. But I think they don't fit well in the modular 
(transportation) design of axis, since they require knowledge about the lower 
level transportation on a higher level.

Carl:That's very interesting.  I'm curious as to more of the details of how 
this functions... If you have one thread waiting on 12 sockets and want to make 
a new call, can this thread begin the next call, or does a second thread open 
the socket and pass the job of waiting on it to the first thread?

I think we would all agree that your use case would benefit from adding this 
capability to Axis2/C.  You mention a potential conflict with the modular 
design of Axis; there is also the idea that making such a powerful feature 
accessible to the average programmer using Axis could be a challenge.  Maybe 
the solution would be to add a new communication mode instead of changing all 
asynchronous communication to one-thread-multi-socket.  I wish I understood the 
Axis2/C architecture
more fully because this would be an interesting area to contribute.

Patric:
But one implementation might be to add another 'configuration structure' (like 
the allocator and thread pool) for socket IO and make that responsible for all 
IO. That implementation can then decide to use one or multiple threads for IO. 
It can use call-backs to signal the completion (or failure or timeout) of the 
IO. The async calls can then be implemented as writing data (by the new io 
struct) and exiting that start-call. Finished. Nothing more to do. No extra 
thread, nothing. Then, when finished, the call-back can be used to parse the 
result and call the user call-back for the result. The io struct (module) 
should probably use a (real!) thread pool for this to prevent one 
time-consuming call to block other calls. But a simple implementation might to 
for the 'average' user. This pattern mimics the io completion port / boost 
interface, so users of axis can easily use these for their async IO.

------
By looking at the above discussion I suggest implementing a new transport for 
Axis2/C using boost library[2] or some other good library that would do the 
job. Boost is based on  Reactor/Proactor I/O design patterns [3]. However this 
would require some changes to Axis2/C engine internals.

Note: In the start of the discussion Carl says "The asynchronous call 
implementation of axis is based on creating new threads that just wait on a 
response"; However I think this is true only if user does not use
axis2_options_set_use_separate_listener(options, env, AXIS2_TRUE); 
call. If this is called then a listener manager thread is started which listen  
on incoming responses. New threads are created only to process the intercepted 
responses.

[1] http://marc.info/?t=122899247800001&r=1&w=2
[2] http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/overview.html
[3] http://www.artima.com/articles/io_design_patterns.html

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to