Skip to content

Producing Work Items

Guglielmo Porcellini edited this page Dec 10, 2017 · 2 revisions

How does the producer know how to split the work?

If you are using the baked in scheduled producer, you will have to either use a factory or a factory method and pass it to the producer.

If you implemented your own producer that's entirely up to you. It is strongly recommended to go through the library code and understanding its mechanisms before trying to use a custom producer. For simplicity the current documentation will only take into account the usage of the built-in scheduled producer as it suits most needs.

Work Item Factories and Factory Methods

When we created the scheduled producer in the [setup][setup], we passed an object reference to a workItemFactory object, together with a schedule. As schedule is nothing else than a Timespan, whilst the workItemFactory is implementing the IWorkItemFactory interface. You could use factory methods instead of the factory and save yourself another class (I prefer implementing the factory for code cleanness and testability). Again, a very simple example:

public class DummyWorkItemFactory : IBatchedWorkItemFactory
{
    public IEnumerable<IWorkItem> CreateStartupWorkItems(
        CancellationToken cancellationToken)
    {
        // This will be called at the startup of the producer only
    }

    public IEnumerable<IWorkItem> CreateWorkItems(
        CancellationToken cancellationToken)
    {
        // This will be called on a schedule
    }
}

This is not particularly, and the only concept that you have to keep in mind is that Breadwinner gives you the possibility of creating very different work items at startup. Whilst the reason behind this choice might not be apparent yet, it will become clearer when we introduce the concepts of a blocking startup and work batches. If you don't want top use this feature, simply leave the method empty or create some standard work items. There is an in the work pool builder that allows you to create a scheduled producer without any startup method.

Batched work items and factory

public class DummyWorkItemFactory : IBatchedWorkItemFactory
{
    public IEnumerable<BatchedWorkItem>CreateStartupWorkItems(
        IWorkBatchFactory workBatchFactory, CancellationToken cancellationToken)
    {
        return GetWorkItems(workBatchFactory, true);
    }

    public IEnumerable<BatchedWorkItem> CreateWorkItems(
        IWorkBatchFactory workBatchFactory, CancellationToken cancellationToken)
    {
        return GetWorkItems(workBatchFactory))
    }

    private IEnumerable<BatchedWorkItem> GetWorkItems(
        IWorkBatchFactory workBatchFactory, bool startup = false)
    {
        var workBatch = 
            workBatchFactory.Create(3, new DummyWorkBatch(), startup: startup);

        var workItems = new List<BatchedWorkItem>();

        for (var i = 0; i < 3; i++)
        {
            workItems.Add(
                new BatchedWorkItem(workBatch, new DummyWorkItem(i.ToString())));
        }

        return workItems;
    }
}

Batches

public class DummyWorkBatch : IWorkBatch
{
    public string Id { get; }

    public DummyWorkBatch()
    {
        Id = Guid.NewGuid().ToString();
    }

    public void DoFinally(
        WorkItemResult result, CancellationToken cancellationToken)
    {
        // Finalize your workbatch

        // Use result.Data to access the data stored in the result 
        // of each work item all aggregated in one collection

        // Use result.Status to assess the overall status of the DummyWorkBatch.
        // If work item failed it will be failed, 
        // if all of them were successfull it will be successful
    }
}