Skip to content

Commit

Permalink
Merge pull request #50 from grei-ufc/block-method
Browse files Browse the repository at this point in the history
Adds support to behaviours to block when the Agent message queue is empty
  • Loading branch information
filipesaraiva authored Jul 10, 2020
2 parents bc2aa1d + 76c187c commit 0b1e67e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pade/behaviours/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def done(self):
'''
pass

def wait(self, timeout):
def block(self, timeout):
''' This method sleeps a behaviour until occurs a timeout. The
behaviour will execute normally afterwards.
'''
Expand Down
4 changes: 4 additions & 0 deletions pade/behaviours/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def done(self):
'''
pass

def block(self):
''' Blocks the behaviour until a new message arrive.
'''
self.agent.message_event.wait()

class OneShotBehaviour(BaseBehaviour):

Expand Down
35 changes: 35 additions & 0 deletions pade/core/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,9 @@ class Agent(Agent_):
Messages received by the agent
messages_lock : threading.Lock
Lock the message stack during operations on the stack
message_event : threading.Event
The Event object that unblock the blocked behaviours when a message
arrives.
"""

def __init__(self, aid, debug=False, ignore_ams=True, wait_time=300):
Expand Down Expand Up @@ -762,6 +765,8 @@ def __init__(self, aid, debug=False, ignore_ams=True, wait_time=300):
self.messages = deque()
# The lock object to ensure thread-safe queue reading
self.messages_lock = threading.Lock()
# An event handler to be launched when a message arrives
self.message_event = threading.Event()

def update_ams(self, ams):
"""Summary
Expand Down Expand Up @@ -806,6 +811,36 @@ def react(self, message):
with self.messages_lock:
if not self.ignore_ams or not message.system_message:
self.messages.appendleft(message)
self.message_event.set()
# Clears the message event in order to block the behaviours again
self.message_event.clear()


def receive(self, message_filter = None):
'''
Get the first message from the top of the message stack (left-side of
the deque) with match the filters provided.
If any filter was provided, return the message from the top of stack.
Parameters
----------
messageFilters : Filter
filter to be applied at the messages
'''

with self.messages_lock:
# Checks if has message without launch another lock. This ensures
# that the method never will raise an 'empty queue' exception.
if len(self.messages) > 0:
if message_filter == None:
return self.messages.popleft()

for message in self.messages:
if message_filter.filter(message):
self.messages.remove(message)
return message
return None


def receive(self, message_filter = None):
'''
Expand Down

0 comments on commit 0b1e67e

Please sign in to comment.