2013/10/21 FUJITA Tomonori <[email protected]>
> On Sat, 12 Oct 2013 20:04:35 +0900
> Satoshi Kobayashi <[email protected]> wrote:
>
> > I noticed that an event between modules may get confused in multithread.
> It
> > is the following scenarios.
> >
> > 1. The module A sends an event to the module B
> > 2. The module B requires time to process the event...
> > 3. The module A sends an event to the module C
> > 4. The module C returns an answer soon
> > 5. The module A is misunderstanding that It is the response from the
> module
> > B (in fact the module C)
> >
> > I wrote PoC reproducing this issue as follows.
>
> Yeah, you need a trick like using request ids to do such. We have been
> thinking about the better way for component communication (such as
> JSON RPC, Message Pack RPC, etc). Also it could be used for
> communication with non Ryu software.
>
> Any proposals?
>
I wrote PoC to avoid confusion on a application. However, this is
troublesome and dirty hack. I grope for the way to avoid on Ryu.
----------
import time
import uuid
from ryu.base import app_manager
from ryu.controller.event import EventRequestBase, EventReplyBase
from ryu.lib import hub
class HasAutogenXid(object):
def __init__(self):
self.xid = uuid.uuid4()
class A2BRequest(EventRequestBase,
HasAutogenXid):
def __init__(self):
super(A2BRequest, self).__init__()
self.dst = 'AppB'
class A2BReply(EventReplyBase):
def __init__(self, dst, xid):
super(A2BReply, self).__init__(dst)
self.xid = xid
class A2CRequest(EventRequestBase,
HasAutogenXid):
def __init__(self):
super(A2CRequest, self).__init__()
self.dst = 'AppC'
class A2CReply(EventReplyBase):
def __init__(self, dst, xid):
super(A2CReply, self).__init__(dst)
self.xid = xid
class AppA(app_manager.RyuApp):
def __init__(self, *args, **kwargs):
super(AppA, self).__init__(*args, **kwargs)
# Request in parallel
hub.spawn(self._request_to_b)
hub.spawn(self._request_to_c)
def _request_to_b(self):
request = A2BRequest()
reply = self._send_request_with_retry(request)
assert isinstance(reply, A2BReply), 'Reply is %s' % reply.__class__
print('The request to B was completed normally')
def _request_to_c(self):
request = A2CRequest()
reply = self._send_request_with_retry(request)
assert isinstance(reply, A2CReply), 'Reply is %s' % reply.__class__
print('The request to C was completed normally')
def _send_request_with_retry(self, request):
reply = self.send_request(request)
while True:
if reply.xid == request.xid:
# This is expected
return reply
# Mistake
self.replies.put(reply)
# Switch other thread
time.sleep(0)
# Retry
reply = self.replies.get()
----------
import time
from ryu.base import app_manager
from ryu.controller.handler import set_ev_cls
from app_a import A2BRequest, A2BReply
class AppB(app_manager.RyuApp):
@set_ev_cls(A2BRequest)
def requst_handler(self, request):
time.sleep(5) # Take time
reply = A2BReply(request.src, request.xid)
self.reply_to_request(request, reply)
----------
from ryu.base import app_manager
from ryu.controller.handler import set_ev_cls
from app_a import A2CRequest, A2CReply
class AppC(app_manager.RyuApp):
@set_ev_cls(A2CRequest)
def requst_handler(self, request):
reply = A2CReply(request.src, request.xid)
self.reply_to_request(request, reply)
----------
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135991&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel