How to escalate top-most supervisors in Akka? - java

I have the following top-level (“parent-most”) actor:
// Groovy pseudo-code
class Master extends UntypedActor {
ActorRef child1
ActorRef child2
ActorRef child3
ActorRef backup
#Override
void onReceive(Object message) throws Exception {
if(message instanceof Terminated) {
Terminated terminated = message as Terminated
if(terminated.actor != backup) {
terminated.actor = backup
} else {
// TODO: What to do here? How to escalate from here?
}
} else {
child1.tell(new DoSomething(message), getSelf())
child2.tell(new DoSomethingElse(message), getSelf())
child3.tell(new DoSomethingElser(message, getSelf())
}
}
#Override
SupervisorStrategy supervisorStrategy() {
new OneForOneStrategy(10, Duration.minutes(“1 minute”, new Future<Throwable, SupervisorStrategy.Directive> {
#Override
Directive apply(Throwable t) throws Exception {
if(isRecoverable(t) { // Don’t worry about how/where this is defined or how it works
SupervisorStrategy.stop()
} else {
SupervisorStrategy.escalate()
}
}
})
}
}
As you can see, it supervises three children, and when those 3 children throw “recoverable” exceptions, they are stopped and are replaced with a backup. So far, so good.
The problem I’m now facing is that if the backup actors throws any throwable whatsoever, I want to consider this Master actor (and really, my app in general) to be in a state where it cannot continue processing any input, and to escalate the exception to the guardian-level.
I’m brand new to Akka and not sure where to put this code, and what it should look like. Again, I just need logic that says:
If the backup actor throws any throwable, escalate the exception to the Master’s parent, which should really be an Akka “guaradian” actor/construct
The first part of this is that we need to know when an exception is thrown from the backup; I can handle this part, so let’s pretend our strategy now looks like this:
#Override
SupervisorStrategy supervisorStrategy() {
new OneForOneStrategy(10, Duration.minutes(“1 minute”, new Future<Throwable, SupervisorStrategy.Directive> {
#Override
Directive apply(Throwable t) throws Exception {
if(wasThrownFromBackup(t)) {
SupervisorStrategy.escalate()
} else if(isRecoverable(t) {
SupervisorStrategy.stop()
} else {
SupervisorStrategy.escalate()
}
}
})
}
But as you can see, I’m still struggling to implement the escalation “out of the actor system”. Ideas? Java code example greatly preferred as Scala looks like hieroglyphics to me.

Have a look at the 'Reaper' pattern here http://letitcrash.com/post/30165507578/shutdown-patterns-in-akka-2 Sorry it is in Scala but I think it is easy enough to translate to Java.
Also have a look here, https://groups.google.com/forum/#!topic/akka-user/QG_DL7FszMU
You should set in your configuration
akka.actor.guardian-supervisor-strategy = "akka.actor.StoppingSupervisorStrategy"
This will cause any 'top level' actor which escalates to be stopped by the system. Then you implement another top level actor called 'Reaper' (or whatever you want to call it) which has just one job, watch the main top level actor and take action (e.g. context.system.shutdown()) when the top level actor stops.
I don't know the akka java API so can't provide you with an exact example, but in Scala, from the LetItCrash blog above, it looks like:
import akka.actor.{Actor, ActorRef, Terminated}
import scala.collection.mutable.ArrayBuffer
object Reaper {
// Used by others to register an Actor for watching
case class WatchMe(ref: ActorRef)
}
abstract class Reaper extends Actor {
import Reaper._
// Keep track of what we're watching
val watched = ArrayBuffer.empty[ActorRef]
// Derivations need to implement this method. It's the
// hook that's called when everything's dead
def allSoulsReaped(): Unit
// Watch and check for termination
final def receive = {
case WatchMe(ref) =>
context.watch(ref)
watched += ref
case Terminated(ref) =>
watched -= ref
if (watched.isEmpty) allSoulsReaped()
}
}
class ProductionReaper extends Reaper {
// Shutdown
def allSoulsReaped(): Unit = context.system.shutdown()
}
In your application startup, you create your master actor, create your reaper, send a WatchMe(masterActor) message to the reaper.

Related

Akka two receiveBuilder in same class

Working with legacy code, inside class which is extended to BaseActor, there two entry points for process messages like that:
private Receive active = receiveBuilder().matchAny((message) -> {
if(message instanceof String){
some code
} else if(...) {
//some code} else {
//some code}
}
and this receiver:
#Override
public Receive createReceive() {
return receiveBuilder().matchAny((message) -> {
if(message instanceof String){
some code
} else if(...) {
//some code} else {
//some code}
}
}
i know that there are typed and untyped actors, but its confusing when enters into active and when into createReceive;
When testing locally always enters into createReceive, on server it enters into active.
if there is only createReceive declared and not active it uses createReceive.
what logic works here, or where i can find docs for it. checked doc.akka.io but still not clear
Receive by itself doesn't do anything : Its just Java glue around class pattern matching. You either return Receive from the createReceive() method (the actors initial pattern matching message loop), or in a getContext.become() call, which then replaces the current active pattern matching message loop with a new one.
The above is described https://doc.akka.io/docs/akka/current/actors.html

How to keep apache camel context alive in thread main

I'm trying to make simple application that will listen one queue from artemis and then proceed messages and after that create new message in second queue.
I have created in method Main Camel context and added routing (it forwards messages to bean). And to test this routing and that this bean works correctly I'm sending
few messages to this queue - rigth after context started in main thread
public static void main(String args[]) throws Exception {
CamelContext context = new DefaultCamelContext();
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616", "admin", "admin");
context.addComponent("cmp/q2", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.addRoutes(new RouteBuilder() {
public void configure() {
from("cmp/q2:cmp/q2").bean(DataRequestor.class, "doSmth(${body}, ${headers})");
}
});
ProducerTemplate template = context.createProducerTemplate();
context.start();
for (int i = 0; i < 2; i++) {
HashMap<String, Object> headers = new HashMap<String, Object>();
headers.put("header1", "some header info");
template.sendBodyAndHeaders("cmp/q2:cmp/q2", "Test Message: " + i, headers);
}
context.stop();
}
And in this case application works fine, but it stops when method main completed - it proceess only messages that were created by it self.
Now after I have test bean that is used in routing, I want to modify application such way that it should start and stay active(keeping camle context and routin alive ) - so that i can create massages manually in web UI (active mq management console).
But I really don't know how.
I have tried infinite loop with Thread.sleep(5000);
I tried to start one more thread(also with infinite loop) in main method.
But it didn't work.(The most suspicious for me in case with infinite loop is that apllication is running, but when i create message in web UI it just desapears - and no any traces in system out that it was processed by my bean in routing, a suppose that it should be processed by my bean or just stay in the queue untouched, but it just disapears).
I now that my question is dummy, but I already have wasted 3 days to find a solution, so any advices or link to tutorials or some valueable information are appreciated.
PS: I've got one painfull restriction - Spring frameworks are not allowed.
I think the most simple solution for running standalone camel is starting it with camel Main. Camel online documentation has also an example of using it http://camel.apache.org/running-camel-standalone-and-have-it-keep-running.html.
I will copy paste the example code here just in case:
public class MainExample {
private Main main;
public static void main(String[] args) throws Exception {
MainExample example = new MainExample();
example.boot();
}
public void boot() throws Exception {
// create a Main instance
main = new Main();
// bind MyBean into the registry
main.bind("foo", new MyBean());
// add routes
main.addRouteBuilder(new MyRouteBuilder());
// add event listener
main.addMainListener(new Events());
// set the properties from a file
main.setPropertyPlaceholderLocations("example.properties");
// run until you terminate the JVM
System.out.println("Starting Camel. Use ctrl + c to terminate the JVM.\n");
main.run();
}
private static class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
from("timer:foo?delay={{millisecs}}")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("Invoked timer at " + new Date());
}
})
.bean("foo");
}
}
public static class MyBean {
public void callMe() {
System.out.println("MyBean.callMe method has been called");
}
}
public static class Events extends MainListenerSupport {
#Override
public void afterStart(MainSupport main) {
System.out.println("MainExample with Camel is now started!");
}
#Override
public void beforeStop(MainSupport main) {
System.out.println("MainExample with Camel is now being stopped!");
}
}
}
The route keeps executing until you hit Ctlr+c or stop it in some other way...
If you test this, notice that you need example.properties file in your classpath, with the property millisecs.
At the very minimum you need a main thread to kick off a thread to run the camel route and then check for when that thread is done. The simple java threading approach using the main loop to check .wait() and the end of the camel route thread to signal .notify() when it finishes (or shutdown) would get the job done.
From there you can look into an executor service or use a micro-container like Apache Karaf
PS. Props for going Spring-free!
Disclaimer: this is written in Kotlin but it is somewhat trivial to port to java
Disclaimer: this is written for Apache-Camel 2.24.2
Disclaimer: I am also learning about Apache-Camel. The docs are a little heavy for me
I tried the Main route to set it up but it quickly got a little convoluted. I know that this is a java thread but I'm using kotlin ATM, I'll leave most of the types and imports available so it's easier for java devs.
class Listener
The first I had to fight with was understanding the lifecycle of Main. It turns out that there is an interface you can implement to add in the implementations of such events. With such an implementation I can hook up any routines that have to be sure that camel has started (no guessing required).
import org.apache.camel.CamelContext
import org.apache.camel.main.MainListener
import org.apache.camel.main.MainSupport
typealias Action = () -> Unit
class Listener : MainListener {
private var afterStart: Action? = null
fun registerOnStart(action:Action) {
afterStart = action
}
override fun configure(context: CamelContext) {}
override fun afterStop(main: MainSupport?) {}
override fun afterStart(main: MainSupport?) {
println("started!")
afterStarted?.invoke().also { println("Launched the registered function") }
?: println("Nothing registered to start")
}
override fun beforeStop(main: MainSupport?) {}
override fun beforeStart(main: MainSupport?) {}
}
class ApplicationCore
Then I set up the configuration of the context (Routes, Components, etc,...)
import org.apache.camel.CamelContext
import org.apache.camel.impl.DefaultCamelContext
import org.apache.camel.impl.SimpleRegistry
import org.apache.camel.main.Main
class ApplicationCore : Runnable {
private val main = Main()
private val registry = SimpleRegistry()
private val context = DefaultCamelContext(registry)
private val listener = Listener() // defined above
// for Java devs: this is more or less a constructor block
init {
main.camelContexts.clear()
listener.registerOnStart({ whateverYouAreDoing().start() })// <- your stuff should run in its own thread because main will be blocked
main.camelContexts.add(context)
main.duration = -1
context.addComponent("artemis", ...)// <- you need to implement your own
context.addRoutes(...)// <- you already know how to do this
...// <- anything else you could need to initialize
main.addMainListener(listener)
}
fun run() {
/* ... add whatever else you need ... */
// The next line blocks the thread until you close it
main.run()
}
fun whateverYouAreDoing(): Thread {
return Thread() {
ProducerTemplate template = context.createProducerTemplate();
for (i in 0..1) {
val headers = HashMap<String, Any>()
headers["header1"] = "some header info"
template.sendBodyAndHeaders("cmp/q2:cmp/q2", "Test Message: $i", headers)
}
context.stop()// <- this is not good practice here but its what you seem to want
}
}
}
In kotlin, initialization is rather easy. You can easily translate this into java because it is quite straight forward
// top level declaration
fun main(vararg args:List<String>) = { ApplicationCore().run() }

How can I make some class, running in the Main Thread, await concurrently for other class to reach some specific state?

I am having serious difficulties to understand how can I make some AsyncTask children, declared and instantiated in the Main Thread, to await for a Service child instance to reach some specific state.
As code examples here is the relevant part for Service; this code does what expected: receives the JSON response and holds it.
public class MyService extends Service {
private boolean received = false;
private string url = "http://someserver.mine/get-data-in-json-format";
// [...]
#Override
public void onCreate() {
doHttpJsonQuery();
}
public boolean responseReceived() {
return this.received;
}
public List<MyModel> getResponseAsObject() {
if (!this.received) return new ArrayList<MyModel>;
// Many code lines that convert the data into a list.
// [...]
return the_list;
}
// [...]
private void doHttpJsonQuery() {
OkHttpClient client = new OkHttpClient.Builder()
.build();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
call.cancel();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
final String myResponse = response.body().string();
//...and some code to hold data as JSONArray
//[...]
}
});
this.received = true;
}
}
This Service works; fine. Then, from another class (which purpose will be to handle persistence inserting the received data in a local Room Database), I try to do the following (here's where my mind is blown):
public class DataRepository {
private MyRoomDatabase db;
private MyModelDao mModelDao;
// I'm skipping irrelevant code on purpose
// [...]
public DataRepository(Application application) {
db = MyRoomDatabase.getDatabase(application);
mModelDao = db.myModelDao();
// [...]
// Here I instance a subclass of ContextWrapper(i named it RemoteDataSource) which
// responsability will be handling different Services for making HTTP operations
mRemoteDataSource = new RemoteDataSource(application.getApplicationContext());
// It holds a reference to MyService. It has some public methods, like this one, to
// control the referenced Service from outside with some encaspsulation
mRemoteDataSource.startMyService();
// Instantiating a private nested class...
PopulateDbAsync mPopulateDbAsync = new PopulateDbAsync(db);
mPopulateDbAsync.doInBackground();
}
// [...]
// Here is the failing code
private class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
PopulateDbAsync(MyRoomDatabase db) {}
#Override
protected Void doInBackground(final Void... params) {
MyService mService = mRemoteDataSource.getMyService();
if (mService == null) {
// This doesn't happen at all right now...
Log.e("MY_ERROR","DataRepository.PopulateDbAsync --> MyService from RemoteDataSource is NULL!!!!");
}
List<MyModel> the_list = mService.getResponseAsObject();
if (the_list == null) {
// HERE! I obtain the NullReferenceException here.
// I am confused about how would I avoid this flaw in my code
Log.e("MY_ERROR", "DataRepository.PopulateDbAsync --> error: response isn't ready yet.");
}
for (MyModel i_model : the_list) {
Log.d("MY_LOG", "DataRepository.PopulateDbAsync --> Inserting data in local DB...");
mModelDao.insert(i_model);
}
return null;
}
}
}
Summarizing: my problem is that I will always get NullReferenceException in this line:
for (MyModel i_model : the_list) {
I am not familiar with multithreading, asyncronous operations and concurrent execution. I have been reading, for two weeks, lots of different documents on the Internet both from Android Official Website and from other websites as well, trying to figure it out... "AsyncTask is not good to perform this kind of operations"... so, what infrastructure should I implement, I have been wondering... should I use Handlers, Threads, Messengers, or what? The more I read, the more confused I get. It's like I have an Analysis Paralysis issue...
Most of the examples I find out there provide too verbose code examples on how to implement multithreading and concurrent execution; while I read them and try to figure out how to implement those structures in my code, I just get stuck; also, with so many classes to choose, I get even more confused...
Due to the HTTP call will need to be performed asyncronously (and response time will not always be the same), I am trying to figure out how to make the piece of code that throws the NullReferenceException "wait" for MyService to complete it's job before starting it's execution; while loops will not work due to it would break Main Thread's lifecycle. "Knowing" if the Service completed it's task or not would be as simple as using the boolean method responseReceived. The big idea is, every time new data is obtained through HTTP, updating the RoomDatabase with it, and, meanwhile, MainActivity would be showing the current local data (if any, or an empty list if there's nothing yet).
So, when I get it, I will understand how to refactor the whole code structure properly to start adding more Service child instances into my RemoteDataSource class, which I created with the idea of having all Service childs that will use OkHttp to perform HTTP communications, wrapped together in a single class for better organization.
What would be the proper way to achieve what I am looking for about this? Would someone be able to provide some short example explaining the code structure I will need for something like this? Examples with empty blocks containing comments like "code to execute when ready here" would be great so I can figure it out.
The question exposed here is related with the same project that made me post this other question some weeks ago; I have been reading here and there, performing some trial-and-error and correcting some code issues here-and-there since then; however, I am making a different question here; finding an answer for this would probably be the first step towards figuring out an answer to the other question as well.
URL References to documentation I have been reading
Some of the documentation I have been reading (but not limited to):
AsyncTask class documentation
Handler class documentation
Basics on Multithreading
Introduction to background processing in Android - Tutorial
Thread With Handlers - Android Example
Messenger class documentation
Well problem is with your application logic as follows,
If you are using AsyncTask that is obviously a separate thread from the main thread. But syncing to your database after retrieving data via HTTP call is a process which has a sequence ( Call through HTTP and retreive -> then persist to database ), it cannot perform asynchronously. So when you call,
List<MyModel> the_list = mService.getResponseAsObject();
this call happens in a particular thread and the program flow is in a different thread.
Since these are asynchronous tasks, they work asynchronously. which means you will never know which one will execute first and which one is next. But as per your logic,
if (the_list == null) {
this part essentially need the_list to be initialized to run. But the problem is at that point, service thread has not finished his work to perform your next logic. so its obvious breaking.
Better if you can re-design this so that you wait for the HTTP request to complete and then persist to database. Because suppose if your HTTP request complets first but still it returns you null or whatever not-desired output. So in that case you need to handle it in your logic.
OK so let me tell you a quick workaround.
Lets use just one thread instead of different threads. So consider changing following line
private class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
to
private class PopulateDbAsync
then you will get an error with
#Override
protected Void doInBackground(final Void... params) {
since we no longer extend AsyncTask class.
so change it as follows, by removing #Override
public Void doInBackground(final Void... params) {
This should fix the stated problem here.
I found a solution: creating custom listeners.
Steps to create a custom listener
1. Define an interface as an event contract with methods that define
events and arguments which are relevant event data.
2. Setup a listener member variable and setter in the child object which can be assigned an implementation of the interface.
3. Owner passes in a listener which implements the interface and handles the events from the child object.
4. Trigger events on the defined listener when the object wants to communicate events to it's owner
I got the NullReferenceException because MyService didn't finish it's job yet. So, first I create the listener's structure within MyService class like this (steps 1 and 2):
private MyServiceListener listener;
public interface MyServiceListener {
public void onDataDownloaded();
}
public void setMyServiceListener(MyServiceListener listener) {
this.listener = listener;
}
And, within the HTTP request's callback (step 4):
#Override
public void onResponse(Call call, Response response) throws IOException {
final String myResponse = response.body().string();
//...and some code to hold data as JSONArray
//[...]
// XXX Trigger the custom event
if (listener != null) {
listener.onDataDownloaded();
}
}
Now, I just can wrap the code that triggered the NullReferenceException within the custom listener like this (step 3):
// Within DataRepository class
mService.setMyServiceListener(new MyService.MyServiceListener) {
#Override
public void onDataDownloaded() {
List<MyModel> the_list = mService.getResponseAsObject();
if (the_list == null) {
// HERE! I obtainED the NullReferenceException here.
Log.e("MY_ERROR", "DataRepository.PopulateDbAsync --> error: response isn't ready yet.");
}
for (MyModel i_model : the_list) {
Log.d("MY_LOG", "DataRepository.PopulateDbAsync --> Inserting data in local DB...");
mModelDao.insert(i_model);
}
return null;
}
}
Actually, the real implementation required to nest this code example into another custom listener following similar steps; but this worked for me.

How can I make this thread safe?

I have a server that receives various xml messages from clients (one thread per client) and routes the messages to different functions depending on the message type. Eg. if the first element in the messages contains the string 'login' it signifies that this is a login message so route the message to the login() function.
Anyway, I want to make this message so things don't get messed up if multiple clients are connected and the dispatcher switches threads in middle of the message routing. So here is how I am routing the messages -
public void processMessagesFromClient(Client client)
{
Document message;
while (true)
{
try
{
message = client.inputStream.readObject();
/*
* Determine the message type
*/
String messageType = getMessageType(message);
// Route the message depending on its type
switch (messageType)
{
case LOGIN:
userModel.handleLogin();
...
...
...
etc...
}
} catch(Exception e) {}
}
So how can I make this thread safe? I figure I need to put a synchronise statement in somewhere but Im not sure where. Also Ive been reading around on the subject and I found this post which says there is an issue with using synchronise on 'this' -
https://stackoverflow.com/a/416198/1088617
And another post here which says singletons aren't suitable for using synchronise on (My class in the code above is a singleton) - https://stackoverflow.com/a/416202/1088617
Your class is already thread safe, because you are only using local variables.
Thread safety only comes into play when you access class state (ie fields), which your code doesn't (seem to) do.
What you are talking about is serialization - you want to funnel all message processing through one point to guarantee that message processing is one-at-a-time (starts and finishes atomically). The solution is simple: Employ a static synchronized method:
public void processMessagesFromClient(Client client) {
Document Message;
while (true) {
processMessage(client);
}
}
private static synchronized processMessage(Client client) {
try {
message = client.inputStream.readObject();
String messageType = getMessageType(message);
// Route the message depending on its type
switch (messageType) {
case LOGIN:
userModel.handleLogin();
...
etc...
}
} catch(Exception e) {}
}
FYI static synchronized methods use the Class object as the lock. This code will make your code behave like a single thread, which your question seems to want.
I would actually have a message handler thread which is responsible for reading incoming messages. This will then hand off processing to a worker thread to do the time consuming processing of the message. You can use the Java ThreadPoolExecutor to manage this.
If you already have 1 thread per connection, then the only thing that you have to synchronize are the functions which handle the events (i.e. functions like userModel.handleLogin()).
I guess the best solution should be to use a thread safe queue like the ConcurrentQueue and use a single working thread to pick up this values and run the actions one by one.
Provided you have one of these objects per thread, you don't have a problem. You only need to synchronized a shared object which can be modified by one of the threads.
public void processMessagesFromClient(Client client) {
while (true) {
processMessage(client);
}
}
private void processMessage(Client client) {
try {
Document message = client.inputStream.readObject();
String messageType = getMessageType(message);
// Route the message depending on its type
switch (messageType) {
case LOGIN:
userModel.handleLogin();
...
etc...
}
} catch(Exception e) {}
}
You need to know which resource should be only used be one thread at a certain time.
In your case it is likely that reading the next message needs to protected.
synchronize (lock) {
message = client.inputStream.readObject();
}
However, your code sample does not really show what needs to protected against concurrent access
The method itself is thread safe.
However, noting that this your class is a singleton, you might want to use double checked locking in your getInstance to ensure thread safety.
Also you should make sure your instance is set to static
class Foo {
private static volatile Foo instance = null;
public static Foo getInstance() {
if (instance == null)
{
synchronized(this)
{
if (instance == null)
instance = new Foo ();
}
}
return instance ;
}
}

Using Command Design pattern

Can anyone explain with a simple example the Command Pattern? I tried searching on the internet, but I got confused.
public interface Command {
public void execute();
}
For the most part, commands are immutable and contain instructions that encapsulate a single action that is executed on demand. You might also have a RuntimeCommand that accepts instructions upon execution, but this delves more into the Strategy or Decorator Patterns depending on the implementations.
In my own opinion, I think it's very important to heed the immutable context of a command otherwise the command becomes a suggestion. For instance:
public final class StopServerCommand implements Command {
private final Server server;
public StopServerCommand(Server server) { this.server = server; }
public void execute() {
if(server.isRunning()) server.stop();
}
}
public class Application {
//...
public void someMethod() {
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(Event e) {
stopCommand.execute();
}
});
}
}
I personally don't really like commands. In my own experience, they only work well for framework callbacks.
If it helps, think of a command in a metaphorical sense; a trained soldier is given a command by his/her commanding officer, and on demand the soldier executes this command.
You can think of Command pattern workflow as follows.
Client calls Invoker => Invoker calls ConcreteCommand => ConcreteCommand calls Receiver method, which implements abstract Command method.
UML Diagram from dofactory article:
Key features:
Command declares an interface for all commands, providing a simple execute() method which asks the Receiver of the command to carry out an operation.
The Receiver has the knowledge of what to do to carry out the request.
The Invoker holds a command and can get the Command to execute a request by calling the execute method.
The Client creates ConcreteCommands and sets a Receiver for the command.
The ConcreteCommand defines a binding between the action and the receiver.
When the Invoker calls execute the ConcreteCommand will run one or more actions on the Receiver.
Code snippet:
interface Command {
void execute();
}
interface Receiver {
public void switchOn();
}
class OnCommand implements Command{
private Receiver receiver;
public OnCommand(Receiver receiver){
this.receiver = receiver;
}
public void execute(){
receiver.switchOn();
}
}
class Invoker {
private Command command;
public Invoker(Command command){
this.command = command;
}
public void execute(){
this.command.execute();
}
}
class TV implements Receiver{
public void switchOn(){
System.out.println("Switch on from TV");
}
}
class DVDPlayer implements Receiver{
public void switchOn(){
System.out.println("Switch on from DVDPlayer");
}
}
public class CommandDemoEx{
public static void main(String args[]){
// On command for TV with same invoker
Receiver receiver = new TV();
Command onCommand = new OnCommand(receiver);
Invoker invoker = new Invoker(onCommand);
invoker.execute();
// On command for DVDPlayer with same invoker
receiver = new DVDPlayer();
onCommand = new OnCommand(receiver);
invoker = new Invoker(onCommand);
invoker.execute();
}
}
output:
Switch on from TV
Switch on from DVDPlayer
Explanation:
In this example,
Command interface defines execute() method.
OnCommand is ConcreteCommand, which implements execute() method.
Receiver is an interface and implementers have to provide implementation for the methods.
TV and DVDPlayer are two types of Receivers, which are passed to ConcreteCommand like OnCommand.
Invoker contains Command. It's the key to de-couple Sender from Receiver.
Invoker receives OnCommand -> which calls Receiver (TV) to execute this command.
By using Invoker, you can switch on TV and DVDPlayer. If you extend this program, you switch off both TV and DVDPlayer too.
You can use Command pattern to
Decouple the sender & receiver of command
Implement callback mechanism
Implement undo and redo functionality
Maintain a history of commands
Have a look at this dzone and journaldev and Wikipedia articles.
Source code as Wikipedia page is simple, cleaner and self explanatory.
You can implement Undo and Redo if you follow the steps as quoted in this article
Here is another example you can use to understand how command pattern works, using real life scenarios: You cannot travel from one place to another by airplane without using the command pattern!
If you are a frequent traveler, all you care about as a client is to travel from where you are to another . you don't care about how the pilot will fly the plane or which airline will be available .. you cant really predict that. all you want is to get the the air port and tell them to take you to your destination.
But if you do that, your command to the airport authorities will be laughed at! they need you to supply a command object, which is your ticket. as much as you don't care about which airline or which plane type, when you are ready to fly, you need to supply a ticket command object. The invoker, which is the airport officials needs to check your command (ticket) so that they can validate it, undo it if it is fake, redo it if they made a mistake (without you having to go through the booking process all over).
In short , they want to have complete control of your command (ticket) before deciding whether or not to invoke or execute your command, which lets the airline (the receiver ) execute ( put you on a plane and take you to your destination) .
Mind you, your command (your ticket) already has the information of the receiver (airline) without which the airport officials wont even start to process your ticket in the first place.
The airport authorities could even have a bunch of tickets they are working on. they may choose to delay my ticket and let someone that came after me go through (invoke another persons ticket before mine)
Here is the code :
[TestClass]
public class Client
{
[TestMethod]
public void MyFlight_UsingCommandPattern()
{
var canadianAirline = new Airline();
AirlineTicket_Command myTicket = new MyAirLineTicket(canadianAirline);
var airportOfficials = new AirportOfficials_Invoker(myTicket);
airportOfficials.ProcessPasengerTicket_And_AllowPassengerToFly_Execute();
//assert not implemented
}
}
public class AirportOfficials_Invoker
{
private AirlineTicket_Command PassengerTicket { set; get; }
public AirportOfficials_Invoker(AirlineTicket_Command passengerTicket)
{
throw new NotImplementedException();
}
public void ProcessPasengerTicket_And_AllowPassengerToFly_Execute()
{
PassengerTicket.Execute();
}
}
public abstract class AirlineTicket_Command
{
protected Airline Airline { set; get; }
protected AirlineTicket_Command(Airline airline)
{
Airline = airline;
}
public abstract void Execute();
}
public class MyAirLineTicket : AirlineTicket_Command
{
public MyAirLineTicket(Airline airline)
: base(airline)
{
}
public override void Execute()
{
Airline.FlyPassenger_Action();
}
}
public class Airline
{
public void FlyPassenger_Action()
{
//this will contain all those stuffs of getting on the plane and flying you to your destination
}
}
My requirement is to perform a sequence of tasks (which can be re-used in several Usecases) each with its own exception flow. Found Command pattern's implementation logical here.
I am trying to make it like each action executed by the command (whether normal/alternate flow) can be an exception handler too. However, If the command is registered with another handler then this should be used. Any suggestions for improvement/correction are welcome.
public interface Command {
Result run() throws Exception;
Command onException(ExceptionHandler handler);
}
public class Result {
}
public interface ExceptionHandler {
void handleException(Exception e);
}
public interface Action {
Result execute() throws Exception;
}
public class BasicCommand implements Command {
private Action action;
private ExceptionHandler handler;
public BasicCommand(Action action) {
if (action == null) {
throw new IllegalArgumentException("Action must not be null.");
}
this.action = action;
this.handler = (ExceptionHandler) this.action;
}
#Override
public Command onException(ExceptionHandler handler) {
if (handler != null) {
this.handler = handler;
}
return this;
}
public Result run() throws Exception {
Result result = null;
try {
result = action.execute();
} catch (Exception e) {
handler.handleException(e);
}
return result;
}
}
public class BasicAction implements Action, ExceptionHandler {
private Object[] params;
public BasicAction(Object... params) {
this.params = params;
}
#Override
public Result execute() throws Exception {
// TODO Auto-generated method stub
return null;
}
#Override
public void handleException(Exception e) {
// TODO exception translation: prepare unchecked application. exception and throw..
}
}
public class Main {
public static void main(String[] args) throws Exception {
int param1 = 10;
String param2 = "hello";
// command will use the action itself as an exception handler
Result result = new BasicCommand(new BasicAction(param1, param2)).run();
ExceptionHandler myHandler = new ExceptionHandler(){
#Override
public void handleException(Exception e) {
System.out.println("handled by external handler");
}
};
// command with an exception handler passed from outside.
Result result2 = new BasicCommand(new BasicAction(param1, param2)).onException(myHandler).run();
}
}
Command Design Patterns decouples invoker of service and provider of service. In general scenario, say for eg., If Object A wants service of Object B, it'll directly invoke B.requiredService(). Thus, A is aware about B. In Command pattern, this coupling is removed. Here, there's an intermediate object known as Command, which comes into picture. Thus, A deals with Command object and command object deals with actual object B. This approach has several applications such as designing applications, which are :-
Accepts commands as requests.
Undoing requests.
Requests requests.
Creating macros.
Creating Task Executors and Task Managers.
For more information regarding, Command Design Pattern, I'll recommend https://en.wikipedia.org/wiki/Command_pattern.
For all other design patterns, refer to https://www.u-cursos.cl/usuario/.../mi_blog/r/head_first_design_patterns.pdf
I would try to give you another rough analogy here.
Suppose that one day God calls on you and tells you that the world's in danger and He needs your help to save it. Further helping you , He tells you that He has sent some superheroes on earth.
Since He doesn't know oops and hence He doesn't call them superheroes (doesn't provide you any interface or abstract class over them) but just tell you their names for ex - batman, superman, iron man and the powers they have.
He also says that in future He might send more such guys in future.
Now He assigns you special responsibility -> control them and for that provides you with seven hands. He doesn't fixes the task of each hand Himself but leaves it on you.
You want flexibility in assigning any hand control of any superhero's power and don't want to repeatedly change things through multiple conditions.
You are in a fix. What do you do now?
Enter Command Pattern.
Create an interface Command and has only one method execute() in it. Encapsulate every power of each superhero and make that implement Command for ex - IronManCreatesSuitCommand
Now you can assign any hand to any command at any time giving you lot more flexibility because now none of your hands cares about the specific task it has to do. You just assign it any command to it. It calls execute on it and the command takes care of everything else.
Now even when God sends any other superhero with different powers, you know what to do.

Categories