Beispiel #1
0
func (a *DeliveryAgent) Process(event ebus.Event) error {
	switch event.Topic() {
	case a.receivedTopic:
		// Received a new order.
		var order Order
		a.err = event.Payload(&order)
		if a.err != nil {
			return a.err
		}
		a.openOrders[order.OrderNo] = true
	case a.packedTopic:
		// Deliver the packed order.
		var shipment Shipment
		a.err = event.Payload(&shipment)
		if a.err != nil {
			return a.err
		}
		delete(a.openOrders, shipment.OrderNo)
		ebus.Emit(len(a.openOrders), "OrderDelivered")
	}
	if len(a.openOrders)%10 == 0 {
		applog.Infof("delivery: topic %q open orders are %d", event.Topic(), len(a.openOrders))
	}
	return nil
}
Beispiel #2
0
func (a *ManufacturerAgent) Process(event ebus.Event) error {
	switch event.Topic() {
	case a.orderedTopic:
		// Store a new manufacturing order.
		var item OrderItem
		a.err = event.Payload(&item)
		if a.err != nil {
			return a.err
		}
		a.openOrders[item.ItemNo] += item.Quantity
	case a.manufacturedTopic:
		// Deliver random numbers of each item.
		a.shipmentNo++
		shipment := Shipment{a.shipmentNo, 0, make(map[int]ShipmentItem)}
		for itemNo, quantity := range a.openOrders {
			shipmentQuantity := rand.Intn(quantity) + 1
			if quantity == shipmentQuantity {
				delete(a.openOrders, itemNo)
			} else {
				a.openOrders[itemNo] = quantity - shipmentQuantity
			}
			shipment.ShipmentItems[itemNo] = ShipmentItem{a.shipmentNo, itemNo, shipmentQuantity}
		}
		ebus.Emit(shipment, "ManufacturingShipped")
	}
	if len(a.openOrders)%10 == 0 {
		applog.Infof("manufacturer: topic %q open orders are %d", event.Topic(), len(a.openOrders))
	}
	return nil
}
Beispiel #3
0
func (a *WarehouseAgent) Process(event ebus.Event) error {
	switch event.Topic() {
	case a.orderedTopic:
		var item OrderItem
		a.err = event.Payload(&item)
		if a.err != nil {
			return a.err
		}
		// Request item from manufacturer.
		if a.openOrders[item.ItemNo] == nil {
			a.openOrders[item.ItemNo] = make(map[int]OrderItem)
		}
		a.openOrders[item.ItemNo][item.OrderNo] = item
		ebus.Emit(item, "ManufacturerItemOrdered")
	case a.shippedTopic:
		// Manufactured items are shipped, add to inventory.
		var shipment Shipment
		a.err = event.Payload(&shipment)
		if a.err != nil {
			return a.err
		}
		for itemNo, item := range shipment.ShipmentItems {
			a.inventory[itemNo] += item.Quantity
		}
	case a.preparedTopic:
		// Order items are prepared and can now be shipped.
		for itemNo, orderItems := range a.openOrders {
			for orderNo, item := range orderItems {
				if a.inventory[itemNo] >= item.Quantity {
					a.shipmentNo++
					shipment := Shipment{a.shipmentNo, item.OrderNo, make(map[int]ShipmentItem)}
					shipment.ShipmentItems[itemNo] = ShipmentItem{a.shipmentNo, itemNo, item.Quantity}
					ebus.Emit(shipment, "WarehouseShipped", item.OrderNo)
					a.inventory[itemNo] -= item.Quantity
					delete(orderItems, orderNo)
				}
			}
		}
	}
	return nil
}
Beispiel #4
0
func (a *OrderAgent) Process(event ebus.Event) error {
	var shipment Shipment
	a.err = event.Payload(&shipment)
	if a.err != nil {
		return a.err
	}
	for itemNo := range shipment.ShipmentItems {
		delete(a.openItems, itemNo)
	}
	if len(a.openItems) == 0 {
		// All done, pack for delivery.
		shipment := Shipment{a.order.OrderNo, a.order.OrderNo, make(map[int]ShipmentItem)}
		for itemNo, item := range a.order.OrderItems {
			shipment.ShipmentItems[itemNo] = ShipmentItem{a.order.OrderNo, itemNo, item.Quantity}
		}
		ebus.Emit(shipment, "OrderPacked")
	}
	return nil
}
Beispiel #5
0
func StartOrderAgent(order Order) error {
	a := &OrderAgent{
		id:           ebus.Id("Order", order.OrderNo),
		order:        order,
		openItems:    make(map[int]bool),
		shippedTopic: ebus.Id("WarehouseShipped", order.OrderNo),
	}
	_, err := ebus.Register(a)
	if err != nil {
		return err
	}
	ebus.Subscribe(a, a.shippedTopic)
	// Emit a request for each order idem.
	for _, item := range order.OrderItems {
		a.openItems[item.ItemNo] = true
		ebus.Emit(item, "WarehouseItemOrdered")
	}
	return nil
}
Beispiel #6
0
// runScenarioTest runs a test with the given number of orders
func runScenarioTest(assert *asserts.Asserts, param scenarioParam) {
	applog.Infof(param.String())
	monitoring.Reset()

	// Prepare test.
	done := make(chan bool)
	provider := config.NewMapConfigurationProvider()
	config := config.New(provider)

	config.Set("backend", "single")

	assert.Nil(ebus.Init(config), "single node backend started")

	StartShopAgent()
	StartWarehouseAgent()
	StartManufacturerAgent()
	StartDeliveryAgent()
	StartWaitAgent(done)

	// Run orders.
	for on := 0; on < param.Orders; on++ {
		order := generateOrder(on)
		err := ebus.Emit(order, "OrderReceived")
		assert.Nil(err, "order emitted")
	}

	select {
	case <-done:
		applog.Infof("order processing done")
	case <-time.After(param.Timeout):
		assert.Fail("timeout during wait for processed orders")
	}

	// Finalize test.
	err := ebus.Stop()
	assert.Nil(err, "stopped the bus")
	time.Sleep(time.Second)
	monitoring.MeasuringPointsPrintAll()
}
Beispiel #7
0
// TestSimpleSingle the single node backend.
func TestSimpleSingle(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	provider := config.NewMapConfigurationProvider()
	config := config.New(provider)

	config.Set("backend", "single")

	err := ebus.Init(config)
	assert.Nil(err, "single node backend started")
	defer ebus.Stop()

	applog.Debugf("registering agents")
	agent1 := ebus.NewTestAgent(1)
	_, err = ebus.Register(agent1)
	assert.Nil(err, "registered agent 1")
	agent2 := ebus.NewTestAgent(2)
	_, err = ebus.Register(agent2)
	assert.Nil(err, "registered agent 2")
	agent3 := ebus.NewTestAgent(3)
	_, err = ebus.Register(agent3)
	assert.Nil(err, "registered agent 3")
	agent4 := ebus.NewTestAgent(4)
	_, err = ebus.Register(agent4)
	assert.Nil(err, "registered agent 4")

	applog.Debugf("subscribing agents to topics")
	assert.Nil(ebus.Subscribe(agent1, "foo", "bar"), "subscribing agent 1")
	assert.Nil(ebus.Subscribe(agent2, "foo", "baz"), "subscribing agent 2")
	assert.Nil(ebus.Subscribe(agent3, "baz", "yadda", "zong"), "subscribing agent 3")
	assert.Nil(ebus.Subscribe(agent4, "foo", "bar"), "subscribing agent 4")

	applog.Debugf("unsubscribing agents from topics")
	assert.Nil(ebus.Unsubscribe(agent3, "zong"), "usubscribing agent 3")

	applog.Debugf("unsubscribing agents from not subscribed topics")
	assert.Nil(ebus.Unsubscribe(agent3, "argle"), "usubscribing agent 3 from not subscribed topic")

	applog.Debugf("deregistering agents")
	assert.Nil(ebus.Deregister(agent4), "deregistered agent 4")
	time.Sleep(100 * time.Millisecond)
	assert.True(agent4.Stopped, "agent 4 is stopped")

	applog.Debugf("emitting events with subscribers")
	ebus.Emit(ebus.EmptyPayload, "foo")
	time.Sleep(100 * time.Millisecond)
	assert.Equal(agent1.Counters["foo"], 1, "counter foo for agent 1")
	assert.Equal(agent2.Counters["foo"], 1, "counter foo for agent 2")
	assert.Equal(agent3.Counters["foo"], 0, "counter foo for agent 3")
	assert.Equal(agent4.Counters["foo"], 0, "counter foo for agent 4")

	applog.Debugf("emitting events without subscribers")
	ebus.Emit(ebus.EmptyPayload, "iirks")
	time.Sleep(100 * time.Millisecond)
	assert.Equal(agent1.Counters["iirks"], 0, "counter iirks for agent 1")
	assert.Equal(agent2.Counters["iirks"], 0, "counter iirks for agent 2")
	assert.Equal(agent3.Counters["iirks"], 0, "counter iirks for agent 3")
	assert.Equal(agent4.Counters["iirks"], 0, "counter iirks for agent 4")

	applog.Debugf("pushing events to many subscribers")
	agents := []*ebus.TestAgent{}
	for i := 5; i < 10000; i++ {
		agent := ebus.NewTestAgent(i)
		agents = append(agents, agent)
		ebus.Register(agent)
		ebus.Subscribe(agent, "flirp")
	}
	time.Sleep(100 * time.Millisecond)
	ebus.Emit(ebus.EmptyPayload, "flirp")
	ebus.Emit(ebus.EmptyPayload, "flirp")
	ebus.Emit(ebus.EmptyPayload, "flirp")
	time.Sleep(100 * time.Millisecond)
	for i := 5; i < 10000; i++ {
		agent := agents[i-5]
		assert.Equal(agent.Counters["flirp"], 3, "counter flirp for agent")
	}
}