Amazon SWF #Signal - java

Is there a way to call an #Signal function from within an Activity in an Amazon SWF Workflow.
I want to be able to notify the workflow that some processing has completed and it should spawn a child workflow for that subset of the processing.
How would this be done?

It sounds like you want to tell workflow that some part of activity is complete, but you want to continue running current activity. If this is the case, then I recommend you to split your activity into 2 parts and use result from first part to tell if child workflow need to be spawned. I don't think that sending signal to workflow in the middle of activity is possible in Flow framework. But you can use raw SWF API to send signal (in this case you'll need to pass "Run ID" to your activity as one of parameters).

The generated workflow external client should be used to send signal from within activity code. ActivityExecutionContext contains all the data necessary to initialize it:
public class MyActivitiesImpl implements MyActivities {
private final ActivityExecutionContextProvider contextProvider = new ActivityExecutionContextProviderImpl();
public void sendSignalBackActivity() {
ActivityExecutionContext context = contextProvider.getActivityExecutionContext();
AmazonSimpleWorkflow service = context.getService();
String domain = context.getDomain();
WorkflowExecution workflowExecution = context.getWorkflowExecution();
MyWorkflowClientExternalFactory factory = new MyWorkflowClientExternalFactoryImpl(service, domain);
GreeterClientExternal workflow = factory.getClient(workflowExecution);
workflow.signalMethod();
}
}
As external client calls SignalWorkflowExecution SWF API it can fail due to intermittent connectivity issues. So an activity implementation might decide to catch and deal (possibly by retrying) with AmazonServiceException which is thrown in such cases.

Related

Multiple Activity Handlers for a Thread

I'm quite new to java and Android programming and have come across the following problem...
I've written a generic thread that sends a message over tcp to a server, waits for a response, then returns the response through a handler to the activity that started the thread.
When the activity needs to send a message to the server, it creates the thread, passing the handler in the constructor.
The handler in the activity processes the response from the server.
The issues is that there are multiple activities that will invoke this thread and each activity will handle responses differently.
For example:
In MainActivity I have a MainActivity.TcpClientHandler
In LightSettingsActivity I have a LightSettingActivitiy.TcpClientHandler
In MainActivity I invoke the thread when I need to send a message and wait a response:
tcpClientThread = new TcpClientThread (serverAddress,serverPort,message,tcpClientHandler);
In LightSettingsActivity, the same:
tcpClientThread = new TcpClientThread (serverAddress,serverPort,message,tcpClientHandler);
In my Thread class, I had to treat these as two different constructors
public TcpClientThread(String addr, int port,String outputMessage, MainActivity.TcpClientHandler handler)...
and
public TcpClientThread(String addr, int port,String outputMessage, LightSettingsActivity.TcpClientHandler handler)...
This doesn't seem very efficient and make my code kind of complex because even when sending the response back to the hander, I need to pay attention to the class that originated the thread,
Like I have to do things like this:
if(threadType == THREAD_MAIN)
handler.sendMessage(Message.obtain(handlerMainActivity, CommonLabels.UPDATE_MSG, inputMessage));
else if(threadType == THREAD_LIGHT_SETTINGS)
handlerLightSettings.sendMessage(Message.obtain(handlerLightSettings, CommonLabels.UPDATE_MSG, inputMessage));
Is there a more efficient way to do this (I tried to use callback instead of handler, but I had a whole set of other problems)?
TcpClientHandler needs to be an interface. LightSettingsActivity and MainActivity need to either implement it or contain an implementation that is specific to them.
When you create a TcpClientThread it looks like this for all handlers
public TcpClientThread(String addr, int port,String outputMessage,TcpClientHandler handler)...
As for the last problem since both activities have their own implementation of TcpClientHandler you do not need to differentiate between them because they are unrelated. In reality using an interface in this fashion is a callback but that is generally how you solve this problem. Because you want to callback to the originator of the request not every class that happens to use TcpClientThread

Multiple threads reading from same socket

I am developing an app which displays data from a server. The server is not mine and it is not very stable. Making too many connections crashes the server.
I have one socket to the server in my main activity, but at times I want to open sub activities which read the data and display it. My problem is that I am unable to achieve this with the same socket and have to open a new socket for every activity.
Every activity has a thread which does the reading from the socket and updates the UI elements on that activity as needed.
To use the same socket in multiple activities, I tried to close the inputReader of an activity before starting the new activity, but that simply make the application hang. If I leave it open, then the new thread in the new activity never receives any data. Killing the thread before starting the new activity is not possible because the thread is generally blocked by the read() function.
Is there anyway that I can have a centralized thread which does the reading and then sends the data to all the other threads in other activities so that I don't have to open new sockets in every activity?
I feel that this is a very basic thing that I am asking, but yet I am unable to find a solution.
A pretty straightforward and simple approach is the following:
You create a new Service which runs in the background and communicates with the server through your socket
The Service receives data from the socket and forwards/broadcasts it to all of your Activities which are interested in receiving it (for example to update the UI) by using the LocalBroadcastManager
All of your Activities implement a BroadcastReceiver and receive the data from your Service inside the onReceive() method
To accomplish that, you should read the introduction to Services and BroadcastReceivers to get an idea of how they work. Also to get a basic overview first, you should read about the available App Components.
EDIT, to answer the question in the comment:
You can always stop the Service by calling stopService() but you can also do it differently if you don't want/need all the functionality of a Service. Instead of a Service you could also create a simple Thread or a HandlerThread which communinicates with the server. From inside of your Thread, you can then forward/broadcast the data to your Activities by using the technique mentioned above (LocalBroadcastManager).
Just to give you an example of the basic structure (code untested though):
class SocketThread implements Runnable
{
static final String SOCKET_DATA_RECEIVED = "com.your.package.SOCKET_DATA_RECEIVED";
static final String SOCKET_DATA_IDENTIFIER = "com.your.package.SOCKET_DATA";
private Context context;
SocketThread(Context c) {
context = c.getApplicationContext();
}
#Override
public void run() { // code running in your thread
// fetch data from socket ...
Intent intent = new Intent();
intent.putExtra(SOCKET_DATA_IDENTIFIER, data); // store data in your intent
// send data to registered receivers
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
// your code ...
}
}
Then you have your Activities, for example MyActivity1, MyActivity2, ... MyActivityN. They all register their embedded SocketDataReceiver to receive the broadcast intent SOCKET_DATA_RECEIVED, which is sent by your thread.
Inside your onReceive() methods you can then extract the data from your intent object by using the identifier SOCKET_DATA_IDENTIFIER.
public class MyActivity1 extends Activity
{
private SocketDataReceiver socketDataReceiver;
#Override
protected void onResume() {
super.onResume();
socketDataReceiver = new SocketDataReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(
socketDataReceiver, new IntentFilter(SocketThread.SOCKET_DATA_RECEIVED));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(socketDataReceiver);
}
private class SocketDataReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// intent contains your socket data,
// get data from intent using SocketThread.SOCKET_DATA_IDENTIFIER
}
}
}
Basically you answered your question yourself:
I can have a centralized thread which does the reading and then sends the data to all the other threads in other activities.
Meaning: of course, such a thing is possible. But you have to sit down, design and implement it. You would start by defining a reasonable interface that allows your other threads to communicate with that central service, something like:
enum RequestType { DO_THIS, DO_THAT };
interface ServerConnectionService<T> {
List<T> performRequest(RequestType request);
}
Meaning: instead of having your different threads do "low level" talking on that socket, you create an abstraction that allows you to say: "when I need this kind of information, then I use my service; and it returns some specific answer to me). Of course, this is a very generic answer, but well, your question isn't exactly specific either.
The next step would then be to have some central (maybe singleton) implementation of that interface; which runs on its own thread, and can be used by other threads in a synchronized, well-defined way.
Final word of warning: if you don't own that server, and it has low quality and is causing trouble for you - that is not a good setup. Because no matter what you do in your code, if the server doesn't do a good job, users will perceive your app to be the problem. Users don't care if an operation fails because some remote server crashes. So the other aspect in your question is: right now, you are in a bad spot. You should spent some serious time to find ways out of there. Otherwise you will be wasting a lot of time to build workarounds for that server you are dealing with.

Asynchronous communication in android

I am trying to integrate apacahe Mina in android.
Can we persist objects using AsyncTask & pass to UI or another class for further use?
for example
public class NetworkConnect extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... param) {
Protocol p = new Protocol(); //here I m making connection with echo server
//Now I want that session in UI to send messages to echo Server
}
}
I want to use this 'p' instance in other class(Like UI) and using this 'p' instance call to attributes of Protocol class.
How to do that? or Is there any alternative solution?
Basically 'Protocol' class should run parallel to UI thread and based on events both should be able to communicate with each other.
Suppose there is echo server...then when someone enter input to 'Input' edittext and hit 'send' button, echoServer will give me back this 'input' again.
Now my problem is that using AsyncTask I am able to connect server, But I am unable to using same session in UI. So I can't send data to server.
Thank you
You just need to store a reference to that object in a field (rather than a local variable like you showed), and provide methods to use it as needed. If it needs to always run on a background thread, then those methods can start an AsyncTask.

How to synchronize concurring Web Service calls in Java

I'm currently developing some web services in Java (& JPA with MySQL connection) that are being triggered by an SAP System.
To simplify my problem I'm referring the two crucial entities as BlogEntry and Comment. A BlogEntry can have multiple Comments. A Comment always belongs to exactly one BlogEntry.
So I have three Services (which I can't and don't want to redefine, since they're defined by the WSDL I exported from SAP and used parallel to communicate with other Systems): CreateBlogEntry, CreateComment, CreateCommentForUpcomingBlogEntry
They are being properly triggered and there's absolutely no problem with CreateBlogEntry or CreateComment when they're called seperately.
But: The service CreateCommentForUpcomingBlogEntry sends the Comment and a "foreign key" to identify the "upcoming" BlogEntry. Internally it also calls CreateBlogEntry to create the actual BlogEntry. These two services are - due to their asynchronous nature - concurring.
So I have two options:
create a dummy BlogEntry and connect the Comment to it & update the BlogEntry, once CreateBlogEntry "arrives"
wait for CreateBlogEntry and connect the Comment afterwards to the new BlogEntry
Currently I'm trying the former but once both services are fully executed, I end up with two BlogEntries. One of them only has the ID delivered by CreateCommentForUpcomingBlogEntry but it is properly connected to the Comment (more the other way round). The other BlogEntry has all the other information (such as postDate or body), but the Comment isn't connected to it.
Here's the code snippet of the service implementation CreateCommentForUpcomingBlogEntry:
#EJB
private BlogEntryFacade blogEntryFacade;
#EJB
private CommentFacade commentFacade;
...
List<BlogEntry> blogEntries = blogEntryFacade.findById(request.getComment().getBlogEntryId().getValue());
BlogEntry persistBlogEntry;
if (blogEntries.isEmpty()) {
persistBlogEntry = new BlogEntry();
persistBlogEntry.setId(request.getComment().getBlogEntryId().getValue());
blogEntryFacade.create(persistBlogEntry);
} else {
persistBlogEntry = blogEntries.get(0);
}
Comment persistComment = new Comment();
persistComment.setId(request.getComment().getID().getValue());
persistComment.setBody(request.getComment().getBody().getValue());
/*
set other properties
*/
persistComment.setBlogEntry(persistBlogEntry);
commentFacade.create(persistComment);
...
And here's the code snippet of the implementation CreateBlogEntry:
#EJB
private BlogEntryFacade blogEntryFacade;
...
List<BlogEntry> blogEntries = blogEntryFacade.findById(request.getBlogEntry().getId().getValue());
BlogEntry persistBlogEntry;
Boolean update = false;
if (blogEntries.isEmpty()) {
persistBlogEntry = new BlogEntry();
} else {
persistBlogEntry = blogEntries.get(0);
update = true;
}
persistBlogEntry.setId(request.getBlogEntry().getId().getValue());
persistBlogEntry.setBody(request.getBlogEntry().getBody().getValue());
/*
set other properties
*/
if (update) {
blogEntryFacade.edit(persistBlogEntry);
} else {
blogEntryFacade.create(persistBlogEntry);
}
...
This is some fiddling that fails to make things happen as supposed.
Sadly I haven't found a method to synchronize these simultaneous service calls. I could let the CreateCommentForUpcomingBlogEntry sleep for a few seconds but I don't think that's the proper way to do it.
Can I force each instance of my facades and their respective EntityManagers to reload their datasets? Can I put my requests in some sort of queue that is being emptied based on certain conditions?
So: What's the best pracice to make it wait for the BlogEntry to exist?
Thanks in advance,
David
Info:
GlassFish Server 3.1.2
EclipseLink, version: Eclipse Persistence Services - 2.3.2.v20111125-r10461
If you are sure you are getting a CreateBlogEntry call, queue the CreateCommentForUpcomingBlogEntry calls and dequeue and process them once you receive the CreateBlogEntry call.
Since you are on an application server, for queues, you can probably use JMS queues that autoflush to storage or use the DB cache engine (Ehcache ?), in case you receive a lot of calls or want to provide a recovery mechanism across restarts.

Android Threads, Services, and two way communication between them

I'm struggling to wrap my head around what needs to happen here. I'm currently working on an app that runs a service. The service when started opens a webserver that runs in a background thread.
At any point while this service is running the user can send commands to the device from a browser. The current sequence of events is as follows.
User sends request to server
Server sends a message to the service via the msg handler construct, it sends data such as the url parameters
The service does what it wants with the data, and wants to send some feedback message to the user in the browser
?????
The server's response to the request contains a feed back message from the service.
The way my functions are set up I need to pause my serve() function while waiting for a response from the service and then once the message is received resume and send an http response.
WebServer.java
public Response serve( String uri, String method, Properties header, Properties parms, Properties files )
{
Bundle b = Utilities.convertToBundle(parms);
Message msg = new Message();
msg.setData(b);
handler.sendMessage(msg);
//sending a message to the handler in the service
return new NanoHTTPD.Response();
}
CommandService.java
public class CommandService extends Service {
private WebServer webserver;
public Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
execute_command(msg.getData());//some type of message should be sent back after this executes
};
Any suggestions? Is this structure the best way to go about it, or can you think of a better design that would lead to a cleaner implementation?
I think the lack of answers is because you haven't been very specific in what your question is. In my experience it's easier to get answers to simple or direct questions that general architecture advice on StackOverflow.
I'm no expert on Android but I'll give it a shot. My question is why you have a Webservice running in the background of a Service, why not just have one class, make your Service the Webservice?
Regarding threading and communication and sleeping, the main thing to remember is that a webserver needs to always be available to serve new requests, whilst serving current requests. Other than that, it's normal that a client will wait for a thread to complete its task (i.e. the thread "blocks"). So most webservers spawn new a thread to handle each request that comes in. If you have a background thread but you block the initial thread while you wait for the background thread to complete its task, then you're no better off than just completing everything on the one thread. Actually, the latter would be preferable for the sake of simplicity.
If Android is actually spawning new threads for you when requests come in, then there's no need for a background thread. Just do everything synchronously on one thread and rejoice in the simplicity!

Categories