Sunday, April 19, 2020

Reactive Architecture: CQRS and Event Sourcing

CQRS/ES stands for Command Query Responsibility Segregation and Event Sourcing. These are different techniques and can be used separately. But when used together, they enable us to built systems which are more resilient and elastic. As is always the case, we need to make trade-offs when we plan to use these techniques.

In traditional style of data persistence, every data update in database removes older state of data and current state is written. So previous state is no more available and we only have current version of data. This approach of persistence is called State Based Persistence. This style captures current state of data, but doesn't tell how we got to it. If we find an issue with current state of the data caused due to some change in past, we can't fix it.

A workaround for the problems faced in state based persistence is to use audit log. Audit log captures all the events in history which led to current state. So we can check which event in the past caused the issue and we can fix the current state. But audit log has its own issues. First, audit log and state can go out of sync. Second, if we store audit log in a file then we can't update data and audit file in same transaction. Also, now we have to decide which of the two is source of truth, data or audit log.

Event Sourcing(ES) is an alternate approach of solving all these issues. ES eliminates persistence of state and only persists the event which causes change in state. Event log is append only. We never modify an existing event or delete it. So ES basically is about capturing the intent, rather than destination. ES thus captures the journey of all the events which led to current state of the system. And to determine state of the system, we just replay the events. We need to take care that side effects related to actual execution of events are avoided when we replay the events. For example, when an event was originally captured, it also send a notification. So while replaying the event to determine current state, we must take care that notification part is not executed.

In most of the cases, number of events we may need to replay to determine current state is not so high. But for some use-cases it may be as high as hundreds or thousands of events. Replaying so many events may hit the system performance. We can make use of snapshot based approach for such scenarios. What it means is that we take snapshot of the state at regular intervals which determines  state of the system at that point of time. And when we need to determine current state we only replay those events which occurred after latest snapshot.

ES provides several advantages in system building:
  • Built in audit log
  • Append only database operations are more efficient than update operations
  • It is easy to rectify the errors made in the past by fixing the bug and obliterating the events and replaying them
It is common for data model to change with time. In case of state based persistence, this is not much of an issue. We can add/remove appropriate columns to the tables and provide default values for records already in the system. But for ES, it is a bit complicated. For ES, event log is sacrosanct. An event in the event log can't be modified or deleted. So if data model evolves, we need to add new version of event log. This adds to complexity in application layer as we need to continue to support older versions of event log. A best practice is to have flexible format for event log, like protobuf. On other hand something like Java serialization highly inflexible.

In Domain Driven Design, we use concepts like aggregate and aggregate root. For example, in a reservation system, we have have reservation as aggregate root and it fits well with writing reservations in the database. But if we want to fetch reservations for a customer, customer becomes a better aggregate root. This shows a conflict between read and write models. An aggregate root seems not to support all possible queries. Moreover, systems generally have different loads for read and write queries. So supporting both read and write with same model is not a good idea.

Command Query Responsibility Segregation(CQRS) is a technique to tackle this problem. This approach is based on having separate models for write and mode database operations. When system receives a command, it goes through write model and when a query arrives it goes through read model. We can have multiple read models based on the use-case. For example, in a reservation system we can have a read model to read reservations based on location(using location as aggregate root) and another read model to fetch reservations based on customer(using customer as aggregate root). And as we have separate models, we can optimize them as per needs. Write model is optimized for writing while read models are optimized for reading. For example, we can make have separate schemas, like we can make read schema denormalized so that joins are not needed, thus making reads fast, or we can use different data stores(polyglot persistence, like Elasticsearch has better read efficiency while Cassandra writes are much more efficient) or we can use different scaling schemes for read and write as per the load requirements.

Though ES and CQRS can be used independently, they are often used together as they compliment each other very well. Write model is used just to persist events. But events are not good candidate for read purposes. So we make use of a process called projection which consumes events and transforms them to a more read friendly form, which is mostly a denormalized form. Read model now reads from this new projected form rather than original events.
CQRS/ES based system also makes it possible to add new read queries easily. We just need to add a new projection to transform events to the desired form. Read and write models can evolve independently as per the needs.

Cost of CQRS/ES

CQRS/ES has various advantages as discussed above, but it also incurs some costs, major being:
  • CQRS model is considered to be more complex
  • May need to maintain multiple data stores
  • More number of classes/objects(commands, events, queries)
  • Higher storage size needed due to even log and data duplication in read model

Saturday, April 18, 2020

Reactive Architecture: Distributed Messaging Patterns

According to the Reactive Manifesto, a critical requirement for any Reactive system is it to be message driven. Message driven systems communicate through asynchronous, non-blocking messages. Such messages help us to build systems that are both resilient, and elastic, and therefore responsive under a variety of situations. But when we choose to build systems using asynchronous, non-blocking messages, there are consequences.

Message Driven Architecture

In a message driven architecture, components communicate using asynchronous non-blocking messages. It means components send messages to other components, but don't wait for response and continue doing other tasks, and final response arrives asynchronously. This ensures that different parts of the system are not waiting on each other. This way of communication provides several key advantages:

  • Resources like threads, CPU cycles etc are not blocked
  • Reduces the contention, and hence improves scalability
  • If a component is down, messages to it can be queued and delivered later on, thus improving reliability of the system
Asynchronous messages must form the backbone of reactive systems. But it doesn't mean that synchronous messaging should never be used. We may need to use synchronous messages, like for acknowledging receipt of a message, even though message is processed asynchronously.

Asynchronous messaging is technically more challenging compared to synchronous messaging. In context of distributed systems, managing a transaction across multiple databases and microservices is difficult as keeping transaction open for a long period of time increases probability of failures and hence makes system brittle.

Saga

A saga is a way of representing a long running transaction. It encapsulates multiples requests, which can either be run in parallel or sequentially. When all requests complete successfully, saga is marked as success. Every request is paired with a compensating action. This is needed for failure scenario. If any of the request fails, compensating action is executed for all requests executed successfully so far, and saga is marked as failure. If a compensating action fails, we keep trying until it is a success.
If a request times out, it may be either that request failed or request succeeded but reply failed or request is queued. Hence we need to make sure that its compensating action doesn't have any negative impact if request itself failed.

Message Delivery Guarantee

In distribute systems, message delivery poses an interesting problem. We always strive for Exactly Once delivery.When component A sends message to component B, it can't be sure whether message was delivered or not. B can send back an acknowledgement, but this itself can be lost in network. So we are never sure of message deliveries. A can retry, but then it may lead to message duplication. This means that Exactly Once delivery guarantee is not possible.
We thus have to settle with following delivery guarantees:

At Most Once Delivery
This approach means that we deliver message just once, and we don't retry in case of failure. As a consequence, message is never duplicated. But as message may be lost, so there is no guarantee of its delivery. It means that receiver would get the message once or never. As we don't retry, so we don't need to store the message. Also it is easy to implement.

At Least Once Delivery
This approach guarantees that every message is eventually delivered. If there is a failure, we retry to send the message. Now failure can be either because message was not delivered or because acknowledgement from receiver failed. So retry may lead to duplication of message, but message is eventually delivered. This also means that we need a durable storage, like file system or database, for the message so that it's not lost.

Messaging Patterns

There are 2 messaging patterns when we build reactive systems.

Point To Point
Point to Point messaging pattern involves components calling each other directly. This means services know each other's API, and if any API is updated, dependent services need to be updated too. This means level of coupling is high, and complexities are more easily observable. Dependencies too are easily observable.

Publish/Subscribe
In this pattern, services are not aware of each other and hence they are not directly coupled. There is a message bus/broker. Services publish their messages to this bus, and other services subscribe to these messages. This means their is high level of decoupling between services, and services are only aware of the message format. We can easily add/replace or remove services without impacting others. Complexities involved are difficult to see. It is bit more difficult to find dependencies as they are not talking directly.

Reactive Architecture: Reactive Microservices

Microservices are a subset of Service Oriented Architecture(SOA). Major point of difference is that SOA doesn't put any constraint upon way of deployment. We can deploy SOA based application as a monolith or individually deploy SOA based services. Microervices strictly require services to be deployed independent of each other. Individual service can be deployed whenever it's needed and it can be deployed on as many number of machines as required.
Major advantages and features of microservices are:
  • Each service can be deployed independently
  • Services can evolve on technologically different path 
  • Each service has it's own database
  • Services can be scaled independently, as per requirement of each service
  • Isolated failures, thus higher availability, fault tolerance and resilient
  • Services communicate synchronously(request-response protocol like HTTP) or asynchronously(reactive microservices)
  • Services are loosely couple
  • Rapid deployments(upto continuous integration)
  • Feature releases as and when ready
  • Teams are more devops oriented

Principles of Isolation

When we talk about correct size of reactive microservices, a better way of putting it is to how to isolate microservices so that they are less coupled and more scalable. Reactive microservices must be tried to be isolated in terms of state, space, time and failure.

Isolation of State
This means that any access to microservice's data is possible only via it's public API. There must be no attempt to directly access microservice's database. This helps in ensuring that microservice can evolve internally without having any impact on other parts of the application. We can keep changing code implementation, data schemas etc as much as we want, but external world remains undisturbed as long as public API of the microservice remains same.

Isolation in Space
It is critical that microservices invoking each other are not impacted by fact that where they are deployed. They may be running on same hardware or different machines or different  data centres. This is called isolation of space. This ensures that we can easily scale up or down the microservices.

Isolation in Time
Reactive microservices communicate through asynchronous non-blocking messaging. This means that they don't wait for each other's response after invocation. This greatly helps in efficient usage of resources like threads, CPU cycles, memory etc., else these resources are kept blocked by request-response style of communication. This is called isolation in time. Also, reactive microservices must expect eventual consistency. This helps in achieving higher scalability. Strong/total consistency requires central coordination which limits scalability.

Isolation of Failure
Isolation of failure means that if a microservice fails then this failure must be restricted to it, and other dependent microservices must continue to function. This makes our system resilient and fault tolerant.

Isolation Techniques

There are several techniques which allow us to achieve above-mentioned levels of isolation.

Bulkheading
Bulkheading has its origin in shipping industry. In ships. we have different sections which are totally isolated from each other, and during accidents if one of the section is filled with water other sections are isolated from it and ship continues to work.
Similarly, in context of reactive architecture, we isolate our components so that failure in a component is limited to it and system continues to perform, even if a bit degraded. A properly bulkheaded system would ensure that failure in one microservice doesn't cascade into other microservices.

Circuit Breakers
Circuit breakers is a mechanism which helps to ensure that components which are already not performing as expected due to heavy stress are not put under more stress. If we keep calling a service which is already failing then we are putting it under more stress. Circuit breakers work in three states. Under normal circumstances, circuit breaker is in CLOSED state and it allows every call to the target service. If service starts failing, circuit breaker goes into OPEN state, meaning it doesn't allow any request to the service and we may return a custom response/exception. Circuit breaker would wait for a configured time period, and once that time period is over, it goes into a HALF-OPEN state and  allows a single request to the target service. If request succeeds, circuit breaker goes into CLOSED state again, else it goes back to OPEN state.

Asynchronous Messaging
In traditional request-response based communication, caller component keeps waiting fro response from called component. This blocks the costly resources like threads, CPU cycles etc. and hence hits the performance of the system. Also, if there is a failure in called service, calling service too fails.
Asynchronous messaging decouples components both in time and failure. Calling service just send a request to another service and keeps doing other stuff, thus totally decoupled in time. There is no blocking of threads, CPU cycles. Also, if a failure is there we can handle it in a much better and easy way.

Gateway Service
Though adding microservices to a system has lots of advantages, like high saclability, resilience, and more isolation in terms of failure. But it also adds more complexity to the system, particularly to the client. Now client may need to make multiple calls to the individual services to aggregate data. To solve this, we may introduce intermediate service between client and the microservices. Intermediate service is called gateway service. Client calls gateway service, which then calls microservices and aggregate the data returned, and send it back to client. We can even have one gateway service per microservice.

Tuesday, April 14, 2020

Reactive Architecture: Domain Driven Design

Domain Driven Design(DDD) is an architectural approach to design large software systems. It has its roots in a book named 'Domain Driven Design: Tackling Complexity in the Heart of Software' by  Eric Evans. Interestingly, rules and guidelines laid down by DDD are highly compatible with those prescribed in reactive architecture. DDD basically emphasizes on breaking a large domain into as small domains as possible. Large domains are difficult to model and breaking them into smaller domains helps in simplifying the overall problem. This decomposition of a large problem into smaller domains result into domain boundaries between those smaller pieces of the overall system.

On the other hand, if we look at microservices architecture, goal is very similar to have self sufficient individual services which cater only a specific functionality of the system with a very well defined API for each microservice and have clear cut functional boundaries in between those individual services. And if we add reactive principle of asynchronous non-blocking interaction between these microservices, what we get is a system consisting of reactive microservices.

Combining DDD with reactive microservices helps us to easily and correctly determine domain/functional boundaries between our microservices, which otherwise is not an easy task. There are reactive platforms available, like Lagom, which are built on ideas and concepts of DDD, and makes it easy for developers to imbibe these ideas into their own application.

Of course, both DDD and reactive architecture can be used separately without other. But compatibility between underlying principles of both is very high and hence both are used together very commonly.

Domain and Ubiquitous language

A domain can be defined as an area of knowledge. For ex ample, in health domain we have doctors, nurses, chemists, hospitals, clinics, medical instruments, disease, pathologists etc. We can express this domain knowledge n various ways. Like, we can use diagrams or documentation. Software is also a way to express this knowledge. In this way, a software becomes an implementation of a domain. People who are involved in such a domain are called domain experts.
DDD is an approach in which we develop our software in a way that it implements a domain model and domain experts can easily relate to it. When we do it, it becomes very easy for domain experts and developers to communicate. The communication language is called Ubiquitous language in DDD terminology and it comes from domain experts. Software developers talk to domain experts and get used to the vocabulary those experts use instead of forcing domain experts to get used to software terms, and over course of time their own domain knowledge improves to expert level. There may be exceptions when software developers have to add some software abstractions to Ubiquitous language due to lack of corresponding word in domain. Basic idea is to have discussions about software without using software jargon.

Breaking the Domain

Domains are quite large and complex in themselves and it's really difficult to model them as a whole. One of the DDD goal is to decompose original domain into smaller sub-domains, so that they can be understood easily. When we do so, each sub-domain has its won ubiquitous language and a model. Combination of model and language for a domain is called its Bounded Context. This way we define bounded contexts for all of our sub-domains. It may happen that there is some duplication of ideas and concepts across sub-domains, but temptation to abstract those concepts must be avoided as with time they evolve and become different.
Bounded Context is one of the most important outcome of domain decomposition and they are very good starting points for reactive microservices. We may need to further break a bounded context into several microservices, but they give us an idea that what parts(bounded contexts) must not be part of same microservice.
We may make use of objects to identify bounded contexts in domain. But a more recent approach is to make use of activities and events to identify bounded contexts. This is called Event First DDD. We may simplify the process by using notation like subject-verb-object. This helps us to have a consistent way of phrasing activities and events. Like, doctor examines patient. Doctor, the subject, performs an action, examines, on an object, patient. Once we phrase all our activities and events in our domain this way, it becomes easy to group together related events and activities, thus giving us a better idea of bounded contexts in the domain.

Domain Activities

Within a bounded context, activities can be divided into several categories.

Command: A command represents a request to perform an action. As it is a request, action asked for hasn't happened yet and it is meant for future. Also, as it is a request, it can be rejected. Important thing about command is that it is meant for a specific recipient, like a microservice, and when that recipient accepts it and executes it, state of the domain undergoes a change. Some examples of command can be like, 'Put an order', or 'Make a reservation'. Recipient of the command can reject the command for any reason it deem fit.

Event: An event represents an action that has already happened, and hence notion of rejection has no meaning to it. Unlike command, event is broadcast to multiple destinations, like multiple microservices. Another conceptual difference with command is that while command causes a change in state of the domain, an event records the change in state. And hence, an event is mostly consequence of a command.

Query: A query represents a request for state of the domain, and request sender expects a response, unlike command or event which don't necessarily warrant a response. A query is generally targeted to a specific recipient. Importantly, a query should never cause a change in state of the domain. If we repeat a query, we always get same response back given there has been no change in the state.

In a reactive system, asynchronous non-blocking messaging is the means of communication. Commands, events, and queries are the types of messages we use in message driven system. These messages form the API of a bounded context(microservice, for example).
If we send a command, 'Make a reservation', with all details needed for it, we don't get a response containing status of the reservation(completed/rejected). What we may get is some sort of acknowledgement of receival of the request. This way of communication is asynchronous in nature. To actually know the status of reservation request, we may need to monitor some event, like 'Reservation completed' or 'Reservation rejected'. This way of communication where we don't wait for response makes system asynchronous and message driven.

Suppose we are working on an application which tries to implement a restaurant system. With help of DDD, we have identified bounded contexts like, Orders, Reservations, Payments, Customers, Menus etc.
When we finally try to implement a bounded context in code, we need to map activities defined in bounded context to software entities. When we do so, we use terms used in ubiquitous language. For example, for command 'Open an Order', we have corresponding class or object named as OpenOrder.

Domain Objects

Finding bounded contexts by defining activities also helps us in defining different types of domain objects. There are several categories of domain objects:

Value Object: A value object is basically meant to represent a piece of information. Two value objects containing same information are functionally same. Value object is immutable, because if we could modify it's information it would functionally become another object. Example for a value object can be an object containing address data. Though main purpose of value object is to contain immutable data, they can also contain some basic business logic, like logic to extract some extra information from its attributes. In a reactive system, value objects are perfect for creating messages which are then passed between different components.

Entity: An entity differs from value object in the sense that it is mutable, but contains an attribute which is immutable and acts as identifier for it. For example, a person can be represented as an entity. Person can have attributes which undergo change, like weight, age etc but it has an identifier attribute(like SSN) which uniquely identifies it. Two persons having same identifier represent same person in the system. Entity contains considerable amount of business logic too, like all rules which control modifications of the attributes. In an actor model, entities are perfect for creating actors as actors have a unique identifier in form of their address, and they have a state which is mutable.

Aggregate: An aggregate is a specific type of object which represents a group of domain objects. At the root of this group is always an entity called as aggregate root, which then contains other domain objects. For example, a Person can have address, phone number and name. This group represents an aggregate with Person as aggregate root and other domain objects like address, phone number and name completing rest of the aggregate. We can't access domain objects contained inside an aggregate directly and we need to go through aggregate root for it. Another important aspect of aggregate is that a transaction should not span across multiple aggregate roots. Doing so means aggregates are not defined correctly or transaction has problems. In reactive systems, aggregates make good candidates for distribution. A very important aspect is figuring out aggregate roots. In many cases we have a single aggregate root per bounded context but that's not always the case.

Domain Abstractions

Apart from activities and domain objects, a bounded context also consists of certain abstractions. A very common example of domain abstraction is service. A service, unlike domain objects, is stateless and is basically meant to implement a specific business logic. This logic is not suitable to be part of a value object or an entity. An accepted design practice is to define an abstraction for a service and then provide concrete implementations for it. Domain just know about the abstraction, and doesn't interact with concrete implementation. This design approach has advantage of replacing one implementation with another when needed.
Having services is a good idea, but too many services in the domain also means that services are doing much of the work and this leads to what we call anemic domain. Before we create a service, we should first try to have the job done by entity or a value object.
Some good candidates for service implementation can be email sender service, hashing service, repository service, factory implementation.


Sunday, April 12, 2020

Reactive Architecture and Actor Model

As compared to traditional applications, modern applications differ mainly in following ways:

  • Distributed: Applications are distributed, i.e installed and running on huge number of machines simultaneously, like tens or even thousands.
  • Data Size: Size of data being handled is much much huge(GBs vs PBs)
  • Active Data: Earlier data usually was at rest, i.e not changing actively once pulled in by a batch job which runs like once in a day. Now data is changing rapidly and we need to keep up our data updated, else we are left behind and it's difficult to catch up.
  • Zero Downtime: In past, applications downtime for maintenance or due to system crash were quite considerably high and acceptable. This is no more true. Users expect to access applications without delay.
  • Fast Response: Modern applications are expected to respond lightning fast. Users have options available, and if applications don't meet their expectations they can very easily move to other options.


Reactive architecture is all about developing applications which are highly responsive, even under heavy load or even if some parts of the application are down. Goal is basically to develop a system which:
  • Can be distributed over hundreds or even thousands of machines
  • Scales from few to millions of users
  • Continues to function even if there are failures
  • Uses only resources required for current load
  • Maintains satisfactory level of responsiveness even under heavy load or under failures
Reactive architecture is based on reactive principles, as described in reactive manifesto.




  • Responsive: A reactive system is responsive, i.e it responds in a timely manner.
  • Resilient: A reactive system remains responsive even when there are failures in the system. Means to achieve this are replication of components, containment of failures, isolation of failures, and delegation of tasks.
  • Elastic(Scalable): A reactive system remains responsive even under varying loads. It means as load varies, system can increase or decrease the resources allocated to handle the requests. As a result, system doesn't have central bottlenecks or contention points.
  • Message Driven: A reactive system makes use of asynchronous non-blocking message passing between different system components to establish a boundary between components that ensures loose coupling, isolation and location transparency. This also enables to communicate failures as messages.

Direction of arrows in above figure tells that being Responsive is facilitated by other three, being Elastic is made possible by  being Message Driven and being Resilient, and being Resilient is made possible by being Message Driven  and being Elastic.

Reactive programming is a programming technique which involves breaking a problem into small discrete steps and then executing those steps in asynchronous non-blocking manner, particularly using language specific techniques and APIs like Futures, Promises, CompletableFutures, Streams, RxJava, RxScala and several others. This is a way of ensuring that system resources like threads, CPU cycles etc. are not blocked.

But reactive programming is different from reactive architecture. Reactive architecture is used at architecture level to create systems or components, like reactive microservices, which follow reactive principles explained above. Merely implementing reactive programming does't mean that system follows reactive principles, though reactive programming tools and means can be used to built reactive systems.

Actor model

Actor model is a reactive programming paradigm which enables us to make reactive systems which follow reactive principles.

All communications between actors in actor model is based on asynchronous non-blocking messaging. And hence it automatically supports elastic and resilient aspects of a reactive system. Some additional facilities provided by actor model, like location transparency, makes it very easy to built highly responsive software systems.

On JVM, Akka toolkit is an implementation of actor model and it helps to build reactive systems. Based on it, additional reactive tools like Lagom and Akka streams are built.

Basic idea behind actor model is to compose the system of entities called Actors. An actor basically encapsulates state and behaviour, just like any other object on JVM. Difference is that actors communicate by sending asynchronous messages to each other rather than by method invocations. This asynchronous communication imparts location transparency to the actors. It means that actors communicate only through this mechanism irrespective of their location and local vs remote communication is merely about configuration. When an actor sends a message to another actor, it first goes to a router, which can also be an actor, and router then routes it to other actor. Other actor can be either residing on same JVM or some other JVM. From original actor's perspective, it has no knowledge of location of the actor which actually receives it and it doesn't even need to know it. Same API is used to send messages to actors, remote or local. This is what location transparency is all about. We just configure routers, and communication mechanism remains same. This makes actor system elastic and resilient. Now we can deploy actors on multiple machines easily. If one of the machine goes down, others are available to share the load, thus making system resilient. Also, if load goes up, we can easily deploy actors on new machines(or remove machines when load goes down), thus making system elastic.

Compared to other reactive programming tools like Rx, Futures,Promises, Streams etc, actor model provides support for all reactive principles. Other approaches support reactive system development partially, and hence we may need to add other tools and techniques like load balancing etc. Actor model, on other hand, supports asynchronous messaging, and being location transparent it enables system to be elastic and resilient. All these reactive principles then add responsiveness to the system. Though we can develop a system using actor model and still not reactive, but using it along with other tools based on it, developing a reactive system becomes much more easy. 

We can built a reactive application without actor model. Like, we can make use of technologies like service registry, service discovery and load balancer to impart location transparency to our system. And then we can add something like a message bus to make asynchronous non-blocking messaging possible between components of the system. This all makes our system message driven, elastic and resilient and hence responsive. But as compared to actor model, these tools and techniques are not built-in, but rather added upon. This means we need additional infrastructure. Another difference is that with these tools we can make systems which are reactive at large scale, like at microservices level. But inside microservices, components may not be reactive. In case of actor model, actors residing inside microservices can be easily made reactive.

Saturday, February 29, 2020

Strategy Pattern

While writing code in OOP we make heavy use of features like inheritance. Inheritance has a major advantage of code re-usability, but it also has some design problems. 
When we create a child class inheriting from a parent class, we create a strong coupling. Any change in parent class also impacts child class too. Every time parent class changes, we need to be sure that child classes' behaviour has not changed unexpectedly, which in turn needs time and efforts spend on testing. If changes are not very frequent and big, we may live with it. But if that is not the case, it may be problematic.
Another problem with inheritance is when some child classes don't want certain behaviours inherited. Programmers try to overcome this problem by overriding the behaviour and providing an empty implementation. This is a hack, not a clean code. Again, this is affordable if we have to do it for rare cases. But if there are too many child classes needing this approach or too many behaviours like this, then this is not a very good way of doing things.
We may be tempted to make use of interfaces here. We declare interfaces for such behaviours and make child classes to implement them only if they need that behaviour. But this badly hurts code re-usability. We may end up with tons of duplicate code in implementations of interfaces. And if we have to make a change a behaviour common to all the implementations, we need to make change in all the implementations. And if its frequent changes, lots of problems to be faced.

Strategy design pattern helps to solve in such scenarios when some parts of our program change too frequently.

Strategy pattern approach is to separate away those parts of our program which vary frequently from those parts which don't, and allow them to evolve in isolation so that they don't impact other parts of the program.


Code Structure



Implementation wise we define interfaces for the behaviours and then implement these interfaces specifically. In other parts of program we make use of these implementations using HAS-A relationship(prefer using interfaces rather than concrete implementations). If  a behaviour has to be changed, those changes are limited to implementation classes and client code is not impacted. We can add new implementations too without changing client code. Whole idea is to ensure that frequently changing code is not part of client code which is stable and is separated out in different classes and used by plugging in those classes as and when needed. And we prefer to program to interfaces for plugging in.

Examples

Collections.sort() method takes a collection and a Comparator as inputs to sort the collection. Comparator interface has method 'compare' which compares two input arguments and returns the result. So Comparator is a 'strategy', and we can implement it as per our needs. Collections.sort is the client which is plugged with Comparator implementation to sort a collection. Concrete implementations of Comparator can evolve in isolation from rest of the program.

Another very good example of strategy pattern can be sorting algorithms. We can implement different sorting algorithms like bubble sort, merge sort, quick sort separately and client code can be plugged with concrete implementation as per need.

Saturday, August 24, 2019

Iterator Design Pattern

Iterator design pattern provides us a way to access the elements in a collection sequentially without exposing internal implementation/representation details to the client.

Programming languages provide a wide variety of collections/aggregates for storing the objects. List, Set, Arrays, Maps etc are very commonly used aggregates used by programmers. We employ different  aggregates for different scenarios and use-cases. But traversing through these aggregates always remains a requirement and is a very basic need in any kind of software program.

As these basic aggregate classes vary in underlying data structures, hence ways of traversing them also varies. We can naively provide methods in aggregates to access the elements, but this can easily expose internal details. Moreover, client code would also need to deal differently with different aggregates even though their need is same(accessing elements sequentially) and hence their are huge chances of code duplication.

Iterator pattern provides a solution to these basic aggregates traversing problems. We basically do two things when we implement iterator pattern.

First, we move the responsibility of traversing the aggregate elements to another class called Iterator. An iterator provides an interface for clients which they can use to traverse the elements. All iterator implementations thus provide this interface.

Second, we make aggregates to provide a simple interface to enable users to get hold of the iterator. Aggregates just need to instantiate appropriate iterator and provide it to client.

These simple structural changes mean several benefits. Aggregate is now only concerned about its core responsibility of storing the elements, while it is now Iterator's responsibility to traverse the elements in the aggregate. It greatly simplifies aggregate interface and also helps in achieving S of SOLID principles. Aggregate just provides interface which clients use to get hold of the iterator. Aggregate has now just two uniform interfaces to deal with irrespective the type of aggregate.

Code structure


Code structure is relatively simple.


Aggregate implements a simple interface which clients invoke to get Iterator instance. Aggregate just needs to instantiate appropriate concrete iterator implementation. Iterator provides clients the ways to traverse though the aggregate elements.

Java Iterators


Java collection classes implement Iterable interface. It maps to Aggregate in aobve UML diagram. This interface has three methods, one of which needs to be implemented by the concrete class(other two have default implementations). This method is named 'iterator' and it returns an Iterator.

Iterator is a simple interface having three basic methods for traversing collection elements:

  • hasNext: returns true is iteration has more elements
  • next: returns next element in iteration
  • remove: removes last element visited
remove has also a default implementation of throwing UnsupportedOperationException. So if a collection class doesn't want to support this method and hence doesn't implement it, exception is thrown to let client know about it.

There are several concrete implementations of Iterator available, like ListIterator. Concrete collection classes instantiates appropriate iterator implementations and return it as implementation of 'iterator' method.

Saturday, August 17, 2019

Template Method Design Pattern

Template Method Pattern is a behavioral pattern. It basically involves defining a method called Template method which defines steps/skeleton of an algorithm and hence controls the overall execution of the algorithm. These individual steps are either implemented in same class or declared abstract so that sub-classes can provide suitable implementation. Template method is made final so that sub-classes can't temper with the structure of the algorithm.

Template method design pattern is heavily employed in development of frameworks. This design pattern helps a lot in avoiding code duplication. Also, algorithm is implemented at a single place and hence it is mush easier to make any changes. This gives much better control over any future modifications.

Code structure



Code setup consists of an abstract class and concrete classes extending the abstract class. Abstract class contains skeleton of the algorithm expressed in terms of a sequence of method calls with each method corresponding to a step in algorithm execution. Some of these methods may be implemented in abstract class and are final so that sub-classes can't change them. Other methods are declared abstract and sub-classes their implementation as per their needs. Template method too is declared final so that sub-classes can't change skeleton of the algorithm.

Some hook methods can also be provided. These are concrete methods but are either empty or provide default implementation. Sub-classes can override them if they want to. Hook methods are heavily used in frameworks, for example as life-cycle methods of various frameworks.

The Hollywood Principle and Template Method

The Hollywood Principle helps to avoid dependency rot in a software system. It basically means that low level components hook into a system but its high level components which decide when and how are low level components are needed. It is popularly phrased as "Don't call us, we will call you".

Template method design pattern also exhibits similar behavior. Parent class controls the flow of the algorithm and invokes sub-class methods whenever needed. Clients interact with parent class abstraction rather than a sub-class implementation. Sub-classes' role is just to provide specific implementations of the steps in algorithm while flow control is determined by parent class only.


Saturday, August 3, 2019

Facade Pattern

Facade pattern is a structural pattern. Like Adapter pattern, it also alters an interface but with the purpose of simplifying it.

Many times we have to work with a complex software system which consists of various parts. These individual parts have their interfaces for clients to work with. We need to use system as a whole to get some work done and this work is done by interacting with different individual parts of the system. Interacting with so many subparts and hence so many interfaces makes our task quite complex and involves many steps.

We can make use of Facade pattern in such situations to simplify interaction with a complex system. We design a simple interface, called as Facade, for client to work with, and Facade internally interacts with different parts of the complex system. So now all the complex implementation of interacting with various interfaces of the complex system is within the Facade and client just needs to interact with this simple interface. Facade doesn't restrict access to low level functionalities of the system and client can still access low level classes if needed. 

Code structure

To implement a Facade, we design a class which is composed of different subparts of the complex system we plan to provide simple interface for. This class is our Facade for that complex system.


Facade is composed of different subparts of the complex system needed to get some work done. Client just interacts with Facade.

Facade pattern is also a way to implement OO design principle of least knowledge(also known as Law of Demeter) in a system. This principle seeks to reduce number of classes an object interacts with as much as possible so that our system is less fragile and less complex to understand. With Facade pattern, client now only interacts with Facade instead of all those subparts in the complex system.


Adapter Pattern

Adapter pattern is a structural pattern. It enables us to make classes work together which otherwise can't because of incompatible interfaces.

Suppose we have an existing software, and we are making use of a third party library to get some work done. Library has an interface exposed to work with it, and hence we have designed our software to be compatible with this interface. But down the line, there is a new library available and it performs better than our current library. So we decide to replace older one with this new super library.  But there is hurdle. New library exposes an interface which is different from interface we have designed our software to. We don't want to change our existing design, and of-course we can't change new library's interface.
Adapter pattern comes to our rescue. It enables us to design a class which sits between our software and new library and acts as a mediator and adapts the new library interface into what our software expects. This mediator class is called Adapter. It basically receives requests from a client and transform them into requests which a receiver can understand.

Code structure

Adapter pattern enables us to encapsulate the changes which we need to do when ever interface we need to work with undergoes a change. This decouples client code from the interface changes, and its the adapter class which undergoes that change and hence client doesn't need to be modified whenever client needs to work against a different interface.


Client only knows of interface it is designed to work with. We call it Target. Adapter class implements Target. It is composed of Adaptee which has the interface Client is not compatible with. but it has the action that Client wants to perform. So Client invokes request on Adapter which delegates the request to Adaptee.
If Adaptee changes, changes we need to make are only in Adapter and hence Client is decoupled from Adaptee.

Adapter pattern is heavy with good OO design principles. Client is bind to an interface, rather than an implementation. Also, Adapter uses composition to wrap the Adaptee. Moreover, we can now use Adapter with subclasses of Adaptee.

Object and class adapter

In Adapter pattern discussion so far we have wrapped Adaptee object inside an Adapter. This is object based approach and it uses composition. We can also have a class based approach wherein Adapter subclasses an Adaptee class. So in class based approach, we use inheritance instead of composition. This reduces flexibility as object based approach enables us to work with subclasses of Adaptee. But in class based approach we can override Adaptee's behaviour.

Example

Older types of Java collections like Vector and Stack provides Enumeration interface to work with these collections. Enumeration has methods to step through the collection, like hasMorElements, nextElement().Later Java versions introduced Iterator interface to iterate step through the new types of Collections, like List. 

If we want to make use of Iterator interface in our code, but are still working with legacy code which exposes Enumeration interface, we can make use of Adapter pattern.

Our code becomes Client, Iterator becomes Target interface, Enumeration class becomes Adaptee. We need to design Adapter class to make our code work with Iterator while underneath Adapter interacts with Enumeration. Two methods in Enumeration directly maps to Iterator methods(hasNext(), next()), but Enumeration doesn't have any method which corresponds to remove() in Iterator. So we make a compromise here, and throw UnsupportedOperationException in our implementation of remove() in Adapter class.



What we may not like

As requests are delegated, so there is an overhead.

Saturday, July 27, 2019

Command Pattern

Command pattern is a behavioral pattern. This pattern allows us to encapsulate a request(receiver, methods, arguments) inside an object, and thus client code can be made free of specific implementations of receiver types, thus decoupling the code.

Suppose we have a class with a method, say performAction(). This method receives an object as argument and has a basic responsibility of interacting with object. Object belongs to a group of objects. These objects get some work done, but unfortunately they don't have a common interface. Instead they have different set of methods to be invoked from performAction(). A very naive implementation of performAction() can be like:


In this implementation, client code is strongly coupled with specific implementation types rather than interface and hence it reduces code flexibility. If there are new types of objects in the system in future for with to deal with, this code would undergo change. This violates 'O' of 'SOLID' principles, and is a source of possible bugs.

Command pattern enables us to get rid of such code implementation and instead we encapsulate requests in objects we call as Command and client code then parametrize invoker(performAction()) with a Command object. We can now dynamically set the Command object, making performAction() interact with different types of object without having this sort of strongly coupled code.

Basically, when we want to decouple an object from making requests to objects which actually perform those requests, we use Command pattern.

Code structure



Command is an interface which has a single method, execute(). Client creates ConcreteCommand which is a specific implementation of Command, and sets Receiver in it. Receiver is the object which contains the actual actions. Invoker has a method setCommand() which Client uses to set Command. It also contains method performAction() which Client calls later on as needed. It is this method which invokes execute() on Command object.
ConcreteCommand basically represents the encapsulation of the request, as it contains the Receiver object and in its execute() it invokes all the required methods of Receiver needed to compete the command.
We can have different concrete Command implementations containing same type of Receiver. They would differ in their invocation of methods on Receiver.

Making use of Command pattern ensures that conditional code from invoker method is no more there and that logic is now expressed in form of different concrete command implementations.

Another way of looking at Command pattern is that it allows us to package a computation(receiver object and actions on it) in an object and pass it around as first class object. Hence, we can invoke computations away from its original point of creation, both in terms of time and space. For example, we can create it in one thread, move it around and then invoke it in another thread. This idea can be applied to many useful use cases like schedulers, thread pools, job queues.

For example, we can implement a queue to which we can add Command objects at one end, and on other end Threads can remove those objects one by one and call execute() method on them. Queue implementation in itself is totally decoupled from the computation aspects. It just acts as a conduit. Thread object just needs to invoke execute() on receiver and it has no other coupling with it. So as long as objects added to queue implement Command interface, we can be sure that execute() method would be invoked on them whenever a Thread is available to remove them from the queue.

Undoing

If our use case is to also support undoing what execute did, then we can add undo() method to Command interface, and in concrete implementation we can then call appropriate method on receiver object in undo().

Example


Runnable interface is a perfect example of Command pattern. Runnable interface corresponds to Command interface in UML diagram above. It has method run() which maps to execute(). We provide concrete implementation for Runnable which corresponds to ConcreteCommand in diagram.



Client code instantiates the concrete Runnable and handover it to a Thread which becomes the Invoker. Client can either set a Receiver explicitly in concrete Runnable or we can have the logic embedded inside run() itself. Thread's start method maps to performAction() in UML diagram above.



What we may not like


If there are many commands in the application, it would lead to too many command classes, and naturally more maintenance efforts.

Saturday, July 20, 2019

Factory Method Pattern

Factory Method Pattern is a creational pattern.

In a framework, we generally have classes representing abstractions and framework needs to manage relationships between objects of these classes, and also creation of these objects. Clients extend these abstract classes for specific implementations. Problem here is that framework only knows abstract classes and not their concrete implementations.

Factory Method Pattern provides a solution to this problem. This pattern allows us to define an interface to create an object, but lets subclasses decide how to implement the interface, thus deferring instantiation to subclasses.
It encapsulates the knowledge of which specific implementations needs to be instantiated and moves this knowledge out of the framework.

Factory Method approach


An abstract method is defined in the abstract creator class. This method is supposed to have the responsibility of creating instances of appropriate product classes. Subclasses of abstract creator class then implement this method to implement creation of  instances of specific products.

We use Factory Method pattern when:
  • A class don't know about specific implementations it need to instantiate
  • A class wants its subclasses to decide which type of objects to be instantiated

Code structure


Code structure we need to implement Factory Method pattern is as follows:

We define an abstract class Creator which contains an abstract factory method. This factory method has contract of returning an instance of type Product, which is another abstract class.
In subclass of  Creator, like CreaotrA and CreatorB, we implement the factory method. Specific implementation creates instance of specific implementation of Product, like ProductA or ProductB.

Consequence of this code structure is that client code(like 'someOperation' method in Creator) is decoupled from concrete implementations of Product as well as creation logic, and it has to deal only with Product interface. Subclasses of Creator are in full control of which type of Product to create without client code being impacted if there are any changes in creation logic.

Basically what we achieve here is to separate object creation logic from the code which uses that object. So down the line object creation knowledge may undergo a change but client code is decoupled from this change. This makes client code adhere to 'O' of SOLID principles.

Also, factory method pattern is one of the way we can implement 'D' of SOLID principles. As now high level component('someOperation' in Creator) does not depend on low level component(different implementations of Product), instead both now depend on abstraction(Product), and thus it introduces 'Dependency Inversion' in our code.

We can have factory method parametrized. This means that method would take an input parameter and use it to decide which product to create. It's a good practice to use enums as parameters to make sure that parameters are type safe.


Parallel class hierarchies


Another way of looking at it is that we encapsulate creation knowledge of a certain type of products into their respective creator. This helps in maintaining parallel class hierarchies. For example, in above UML diagram CreatorA is responsible for creating instances of ProductA, while CreatorB is reposnsible for creating instances of ProductB. Both creators are subclasses of Creator while both products are subclasses of Product. So we have two parallel class hierarchies evolving here and factory method is the connection between them.

What we may not like about Factory Method?


If a new type of Product has to be instantiated and existing Creator implementations are not a good fit to create it, then we may have to create a new Creator subclass for it. This is a bit of overhead just to instantiate a new type of Product.


Saturday, July 13, 2019

Decorator pattern

Decorator pattern falls under category of structural patterns. Purpose of Decorator pattern is to enable us to add additional features to an object dynamically at run time.

Why not subclassing?


One may argue to make use of subclassing an existing class to add additional features/functionalities to our class, and hence to its objects. This is in fact a well practiced approach, but it has some disadvantages apart from strong coupling between parent and child class.
First, parent class behaviour is added to all objects of the child class which may not be desired. Second, a behavior inherited from a parent class is locked into child class at compile time, and hence we can't influence the time at which we actually want object to have a particular behaviour.
Another major disadvantage can be that if there is scope for a large number of combinations of these behaviours in our system and we make classes for all possible combinations, then it may lead to class explosion, leading to huge maintenance problem.

Decorator pattern


Decorator pattern enables us to add additional features/responsibilities to the objects at run time in a very flexible manner. We can decide which behaviour to be added, when to be added, how to be added.

Decorator approach


Target object which we want to have a specific feature is wrapped inside another object having that feature. Enclosing object is called decorator, and importantly it has same interface as target object so that client code can invoke same interface. When client sends a request, decorator object forwards that request to target object and additionally add its own action(decoration) before or after it. Multiple decorators can be applied recursively, hence allowing to add as many features as we want.
We define the interface of the target object/class. And we define an abstract Decorator class which implements this interface, so now it has same interface as target object and client can invoke calls on it transparently.This abstract class also contains the reference to target object. We implement concrete classes for Decorator,wherein we direct client requests to target object.And while it does so,it also performs the 'decoration'.

Please keep in mind that all class based inheritance done here is just to make sure that a common interface is maintained across all objects involved in the process. Hence, we don't suffer from the disadvantages we discussed above in context of subclassing.

Code structure


Lets look into code structure we need to have to implement Decorator pattern.

UML diagram is as follows:



First, we have a class to define a common interface to be used by clients transparently:


We implement functionality in a class:

Our aim is to add additional features to objects of  SimpleComponent at run time.

So we define an abstract decorator class:


Now we add specific decorators:

Lets now put it all together and see how it works:

Running this program would give following output:
Core functionality implemented here
Decoration done by DecoratorB
Decoration done by DecoratorA

So, we are able to add behaviours to target object dynamically. If needed, we can add additional features as and when we want, thus handing lots of flexibility to our system.

Example


java.io package can be looked into to see working example of Decorator pattern.

InputStream is an abstract class and is super class for all classes representing an input stream of bytes. It has an abstract method read() which every subclass needs to implement. This class can be mapped to Component class in UML diagram above.

There are several concrete implementations of InputStream, like FileInputStream which reads bytes from a file in the file system. FileInputStream can be mapped to SimpleComponent in our UML diagram.

There is another class, FilterInputStream. This class extends InputStream and contains some other input stream, which it uses as basic source of bytes, and possibly transforms the data or provides additional functionality. It can be mapped to Decorator class in UML diagram.

Finally, there are classes which extend FilterInputStream, like BufferedInputStream. This class adds functionality of buffering the input data.

So, if we need to read data from a file one character at a time:


What we may not like about Decorator?


A quite obvious downside of Decorator pattern is that sometimes it leads to too many small classes in the system which makes it easy to understand and debug.



Saturday, May 5, 2018

Asynchronous Programming with Futures and Promises

In multi-threaded programs synchronization is a mechanism commonly used to avoid various issues faced in concurrent programming,like race conditions, ordering.But this mechanism has its own pitfalls, like deadlocks, starving threads etc.
Asynchronous programming attempts to deal with issues. This is a programming style in which tasks are executed independently of the main thread flow. Futures and Promises are the main abstractions in asynchronous programming.

Futures

In a concurrent program, multiple computations are executed on entities called threads. At any given point of time, a thread may be stuck as it is waiting for a condition to be fulfilled. Like, a thread is executing a method which makes a call over the network to fetch some data and construct a string from this data and return it. 
def getDataFromServer(): String
But call over network may be very time consuming, and hence thread has to wait for method to return.Waiting threads are not a good idea when resources are limited.So a better way is to block the thread.
But blocking the thread has it's own side effects. Scala provides a solution to this problem.We change the return value of the method from string to something which can be returned immediately.This return value is called future.A future is a placeholder, that is a memory location for the value. It doesn't need to contain a value when it is created, and a value can be placed eventually into the future by the method. We can change method signature as:
def getDataFromServer(): Future[String]
Future[String] type means that future object can eventually contain a String object. Method can now be implemented without blocking-server call can be made asynchronously and when returned data is available, it is converted into a String and placed in the future, this completing the future. And once a future is completed, it can't be changed.

In Scala, futures has two aspects:future value and future computation.
A future value,Future[T], denotes a value of type T which might not be available currently but may be available later. In scala.concurrent package, futures are represented by trait Future[T].
A future computation represents an asynchronous computation which that generates a future value. In Scala, a future computation can be started by calling apply method on Future companion object.
def apply[T] (b: => T)(implicit e: ExecutionContext) : Future[T]
apply method takes a by-name parameter of type T. This is basically the body of the asynchronous computation which produces a value of type T.It also takes an implicit parameter of type ExecutionContext which takes care of when and where to execute a thread. apply method returns a future of type T, and is completed with the value returned by asynchronous computation b.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.globalobject FuturesDemo extends App{
  Future{println("Future is here")}
  println("Future is coming")
  Thread.sleep(500)
}

The order in which two println are called in in-deterministic.

To read the value from future, we can poll it for it's completion status:
object ReadFutureValueDemo extends App{
  val sbtFile = Future{
    val f = Source.fromFile("build.sbt")
    try f.getLines.mkString("\n") finally f.close()
  }
  println(s"started reading the build file asynchronously")
  println(s"status: ${sbtFile.isCompleted}")
  Thread.sleep(250)
  println(s"status: ${sbtFile.isCompleted}")
  println(s"value: ${sbtFile.value}")
}
Future callbacks

Polling a future for it's completion is not a good approach. A much better way is to make use of future callback. A callback is a function which gets executed when it's arguments are available. When we set a callback on a future, it gets called when future gets completed. foreach method is commonly used method to set a callback on a future. Important to note that callback is not invoked immediately after future is completed. Execution context schedules asynchronous task to execute the callback. So, future computation may run on a thread different from main thread, and callback may be executed on a totally different thread.
Moreover, we can set multiple callbacks on a future.
object FutureCallbackDemo extends App{
  def getUrlSpec(): Future[List[String]] = Future {
    val url = "http://www.w3.org/Addressing/URL" +
      "/url-spec.txt"        val f = Source.fromURL(url)
    try f.getLines.toList finally f.close()
  }
  val urlSpec: Future[List[String]] = getUrlSpec()
  def find(lines: List[String], keyword: String): String = {
    lines.zipWithIndex collect {
      case (line, n) if line.contains(keyword) => (n, line)
    } mkString ("\n")
  }
  urlSpec foreach{
    case lines => println(find(lines,"telnet"))
  }
  urlSpec foreach {
    case lines => println(find(lines, "password"))
  }
  println("Continue with other work")
  Thread.sleep(5000)
}
Futures and exceptions

If future computation throws an exception, future object cannot be completed with a value. It means future has failed.
foreach method only takes those callbacks which can handle successful future objects. failed method can work with failed objects. It returns Future[Throwable] object that contains exception with which future computation failed, and it can be used with foreach.
object FuturesFailureDemo extends App{
  val urlSpec: Future[String] = Future {
    val invalidUrl = "http://www.w3.org/non-existent-url-                    spec.txt"    Source.fromURL(invalidUrl).mkString
  }
  urlSpec.failed foreach {
    case t => println(s"exception occurred - $t")
  }
  Thread.sleep(1000)
}
We can also handle both future success and failure in same callback by using type Try[T]. The type Try[T] has two implementations:Success[T] which encodes result of successful future computation and Failure[T] which encodes the Throwable object that failed the future computation.
There are some Throwable objects which are not stored in a Future. These are miany fatal exceptions like InterruptedException,LinkageError, VirtualMachineError, ThreadDeath etc.

Promises

Promises are objects which can be assigned a value or an exception only once(hence also called single-assignment variable). It is represented with type Promise[T] in Scala. We make use of Promise.apply method in Promise companion object. This method returns an instance of Promise and is non-blocking. But unlike Future.apply, it doesn't start a asynchronous computation. It just creates a promise object. When a promise instance is created, it doesn't contain a value or an exception, just like a future object. Every promise object corresponds to exactly one future object,and to obtain associated future we call future method on promise. Same future object is returned on multiple calls of this method.
This way we can say that promise-future represent two aspects of single-assignment variable. Promise enables us to assign a value to a future object, while future allows us to read that value.
Once a promise has been successfully completed or failed, it can't be assigned another value or exception in any way.
A promise is assigned a value using success or failure.
object PromisesDemo extends App{
  val p = Promise[String]
  val q = Promise[String]
  p.future foreach { case x => println(s"p succeeded with                 '$x'") }
  Thread.sleep(1000)
  p.success("assigned")
  q.failure(new Exception("not kept"))
  q.future.failed foreach { case t => println(s"q failed     with $t") }
  Thread.sleep(1000)
}