def test_multiple_actors(self): for name in range(0, 10): _actor = TaskQueueActor(name, self.clock) self.cast.add_member(_actor) idle_task = Idling() _actor.allocate_task(idle_task.idle, idle_task) self.cast.initiate_shutdown() self.cast.start() self.clock.start() self.cast.wait_for_shutdown() for actor in self.cast.members: self.assertEqual('idle()[0->1]', str(actor.last_task))
def test_multiple_starts(self): self.cast.add_member(TaskQueueActor('alice', self.clock)) self.cast.start() self.cast.start() self.cast.initiate_shutdown() self.clock.tick() self.cast.wait_for_shutdown()
def __init__(self, specification, plan_spec, number_of_developers, number_of_clock_ticks, number_of_projects, number_of_traces, max_trace_length, random): self.number_of_traces = number_of_traces self.max_trace_length = max_trace_length self.software_projects = list() for seed in range(0, number_of_projects): clock = SynchronizingClock(number_of_clock_ticks) development_team = Cast() for logical_name in range(0, number_of_developers): development_team.add_member(TaskQueueActor( logical_name, clock)) centralised_vcs_server = CentralisedVCSServer(SoftwareSystem()) plan = plan_spec(specification, centralised_vcs_server, random) software_project = SoftwareProject(clock, development_team, plan, random) self.software_projects.append(software_project) self.simulation_duration = -1
def test_non_blocking_for_actors(self): seconds_clock = SynchronizingClock(max_ticks=3600) minutes_clock = SynchronizingClock() hours_clock = SynchronizingClock() seconds_clock.add_tick_listener(InterClockSynchronization(minutes_clock, granularity=60)) minutes_clock.add_tick_listener(InterClockSynchronization(hours_clock, granularity=60)) actor = TaskQueueActor(0, minutes_clock) example_workflow = ExampleWorkflow() actor.allocate_task(example_workflow.task_a, example_workflow) actor.initiate_shutdown() actor.start() while hours_clock.current_tick < 1: seconds_clock.tick() self.assertEqual(actor.last_task.finish_tick, 2) self.assertEqual(3600, seconds_clock.current_tick) self.assertEqual(60, minutes_clock.current_tick) self.assertEqual(1, hours_clock.current_tick)
def test_add_member(self): self.cast.add_member(TaskQueueActor('alice', self.clock)) self.assertEqual(1, len(self.cast.members))
def setUp(self): self.clock = SynchronizingClock(max_ticks=4) self.actor = TaskQueueActor(0, self.clock) self.idling = Idling() self.example_workflow = ExampleWorkflow(self.idling)
class ActorTestCase(TestCase): def setUp(self): self.clock = SynchronizingClock(max_ticks=4) self.actor = TaskQueueActor(0, self.clock) self.idling = Idling() self.example_workflow = ExampleWorkflow(self.idling) def run_clock(self): self.actor.start() self.clock.start() self.clock.wait_for_last_tick() def test_explicit_idle(self): self.actor.allocate_task(self.idling.idle, self.idling) self.actor.initiate_shutdown() self.run_clock() self.assertEquals(1, self.actor.last_task.finish_tick) def test_idling_when_nothing_to_do(self): self.run_clock() self.assertEquals(0, len(self.actor.task_history)) def test_finish_tasks_before_shutdown(self): self.actor.allocate_task(self.idling.idle, self.idling) self.actor.allocate_task(self.idling.idle, self.idling) self.actor.allocate_task(self.idling.idle, self.idling) self.actor.initiate_shutdown() self.run_clock() self.assertEquals(3, self.actor.last_task.finish_tick) def test_idling_when_nothing_to_do_after_completed_task(self): self.actor.allocate_task(self.idling.idle, self.idling) self.run_clock() self.assertEquals(1, self.actor.last_task.finish_tick) def test_nested_task(self): self.actor.allocate_task(self.example_workflow.task_a, self.example_workflow) self.actor.initiate_shutdown() self.run_clock() self.assertEquals(self.actor.last_task.finish_tick, 3) def test_encounter_exception_shutdown_cleanly(self): self.actor.allocate_task(self.example_workflow.task_c, self.example_workflow) self.run_clock() self.assertEquals('task_c()[0->1]', str(self.actor.last_task)) def test_insufficient_time_shutdown_cleanly(self): """ Demonstrate that actors can shutdown cleanly if their allocated tasks proceed beyond the maximum clock time. """ self.actor.allocate_task(self.idling.idle_for, self.idling, [5]) self.run_clock() self.actor.shutdown() self.assertEquals(5, len(self.actor._task_history[0].sub_tasks)) self.assertEquals(None, self.actor._task_history[0].finish_tick) def test_stateless_task_allocation(self): @default_cost(1) def example_task(): pass self.actor.allocate_task(example_task) self.run_clock() self.assertEquals('example_task()[0->1]', str(self.actor.last_task)) def test_task_with_implicit_state_allocation(self): self.actor.allocate_task(self.example_workflow.task_b) self.run_clock() self.assertEquals('task_b()[0->2]', str(self.actor.last_task))
import grpc import do_work_pb2_grpc import do_work from concurrent import futures from theatre_ag import Cast, Episode, SynchronizingClock, TaskQueueActor, default_cost from wait_for_tick_workflow import WaitForTickWorkflow from improv import Improv clock = SynchronizingClock(max_ticks=10) cast = Cast() tick_listening_actor = TaskQueueActor('tick_listener',clock) cast.add_member(tick_listening_actor) improv = Improv(clock, cast) wait_for_tick_workflow = WaitForTickWorkflow(improv) tick_listening_actor.allocate_task(wait_for_tick_workflow.the_main_entry_point) improv.perform() service = do_work.Service(improv) grpc_server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) do_work_pb2_grpc.add_SimulateServiceServicer_to_server(service, grpc_server) grpc_server.add_insecure_port('[::]:9000') grpc_server.start() grpc_server.wait_for_termination()
from theatre_ag import SynchronizingClock, TaskQueueActor from pyagora import ContinuousOrderDrivenMarket, OrderBookClearingWorkflow, Stock, RandomTraderWorkflow, \ TradeRange, LimitBuyOrder, LimitSellOrder, SafeTradingAccount from random import Random clock = SynchronizingClock(max_ticks=10000) random = Random(1) lemons = Stock('lemons') market_clearer = TaskQueueActor('market', clock) continuous_order_driven_market = ContinuousOrderDrivenMarket(lemons, clock) order_book_clearing_workflow = \ OrderBookClearingWorkflow(continuous_order_driven_market, trade_pricer=lambda so, bo: bo.limit_price if bo.tick < so.tick else so.limit_price, trade_check=lambda so, bo: bo.limit_price >= so.limit_price) market_clearer.allocate_task(order_book_clearing_workflow.operate) trading_account = SafeTradingAccount( name='trader', cash=1000, inventory={lemons: 100}, ) trader = TaskQueueActor('trader', clock)
def assign_task_to_new_actor(self, entry_method): eve = TaskQueueActor('eve', self.episode.clock) self.episode.cast.add_member(eve) eve.allocate_task(entry_method) eve.start()