Play! Framework: Reuse of instances over multiple requests - java

I develop an application using the Play! Framework which makes heavy use of the javax.script Package, including the ScriptEngine. As ScriptEngines are expensive to create and it would make sense to use them across multiple requests (I don't bother to create multiple ScriptEngines, one per Thread - at least i won't create ScriptEngines for each Request over and over).
I think this case is not restriced to ScriptEngines, there might be something in the framework I'm not aware of to handle such cases.
Thank you for any ideas you have!
Malax

Play is stateless, so there is no "session-like" mechanism to link an object to a user. You may have 2 alternatives:
Use the Cache. Store the ScriptEngine in the cache with a unique ID, and add a method that checks if it's still there. Something like:
public static Engine getScriptEngine(Long userId) {
String key = "MY_ENGINE" + userId;
ScriptEngine eng = (ScriptEngine) Cache.get(key);
if(eng == null) {
eng = ScriptEngine.create();
Cache.put(key, eng);
}
return eng;
}
Or create a singleton object that contains a static instance of the ScriptEngine so it's always there once the server starts.
I would say the Cache one is the best approach.
EDIT: on your comment, this will depend on situation:
If you want to reuse a Engine across multiple request of a unique user (that is, each user has his own ScriptEngine to work with) the cache method works as the cache links the Engine to the user id. This would solve any threading issue too.
Otherwise, if you want to reuse it across multiple requests of multiple users, the static method is a better approach. But as you mention the access won't be thread safe, in Play or in any system.
I'm thinking your best bet is to work asynchronously with them. I don't know how you will use the ScriptEngines, but try to do something like this:
On request, store an entry in a table from the db marking a ScriptEngine processing request
In the same request, launch an asynchronous job (or have on running every 30 seconds)
The job will read the first entry of the table, remove it, do the task, return answer to the user. The job may have a pool of ScriptEngine to work with.
As jobs are not launched again while a current job is working, if you have enought requests the job will never cease working. If it does it means that you don't need engines at that time, and they will be recreated on demand.
This way you work linearly with a pool, ignoring threading issues. If you can't do this, then you need to fix the thread-safety of your ScriptEngine, as you can't pretend to share an object that it's not thread safe in a server environemnt which spawns multiple threads :)

Why don't you implement a Script-Pool? So each request get a instance from the pool the same way as a JDBC-Connection-Pool.
But make sure the Script-Engine is stateless.

Related

Is Session.sendToTarget() thread-safe?

I am trying to integrate QFJ into a single-threaded application. At first I was trying to utilize QFJ with my own TCP layer, but I haven't been able to work that out. Now I am just trying to integrate an initiator. Based on my research into QFJ, I would think the overall design should be as follows:
The application will no longer be single-threaded, since the QFJ initiator will create threads, so some synchronization is needed.
Here I am using an SocketInitiator (I only handle a single FIX session), but I would expect a similar setup should I go for the threaded version later on.
There are 2 aspects to the integration of the initiator into my application:
Receiving side (fromApp callback): I believe this is straightforward, I simply push messages to a thread-safe queue consumed by my MainProcessThread.
Sending side: I'm struggling to find documentation on this front. How should I handle synchronization? Is it safe to call Session.sendToTarget() from the MainProcessThread? Or is there some synchronization I need to put in place?
As Michael already said, it is perfectly safe to call Session.sendToTarget() from multiple threads, even concurrently. But as far as I see it you only utilize one thread anyway (MainProcessThread).
The relevant part of the Session class is in method sendRaw():
private boolean sendRaw(Message message, int num) {
// sequence number must be locked until application
// callback returns since it may be effectively rolled
// back if the callback fails.
state.lockSenderMsgSeqNum();
try {
.... some logic here
} finally {
state.unlockSenderMsgSeqNum();
}
Other points:
Here I am using an SocketInitiator (I only handle a single FIX session), but I would expect a similar setup should I go for the threaded version later on.
Will you always use only one Session? If yes, then there is no use in utilizing the ThreadedSocketInitiator since all it does is creating a thread per Session.
The application will no longer be single threaded, since the QFJ initiator will create threads
As already stated here Use own TCP layer implementation with QuickFIX/J you could try passing an ExecutorFactory. But this might not be applicable to your specific use case.

Creating Threads with java in AppEngine Standard Environment

I'm new in Google Cloud Platform. I'm using AppEngine standard Environment. I need to create Threads in java but I think it's not possible, is it?
Here is the situation:
I need to create Feeds for users.
There are three databases with names d1, d2, d3.
Whenever a user sends a request for feeds Java creates three threads, one for each database. For example t1 for d1, t2 for d2 and t3 for d3. These threads must run asynchronously for better performance and after that the data from these 3 threads is combined and sent in the response back to user.
I know how to write code for this, but as you know I need threads for this work. If AppEngine standard Env. doesn't allow it then what can I do? Is there any other way?
In GCP Documentation they said:
To avoid using threads, consider Task Queues
I read about Task Queues. There are two types of queues: Push and Pull. Both run asynchronously but they do not send a response back to the user. I think they are only designed to complete tasks in the background.
Can you please let me know how can I achieve my goal? What things I need to learn for this?
Note: the answer is based solely on documentation, I'm not a java user.
Threads are supported by the standard environment, but with restrictions. From Threads:
Caution: Threads are a powerful feature that are full of surprises. To learn more about using threads with Java, we recommend
Goetz, Java Concurrency in Practice.
A Java application can create a new thread, but there are some
restrictions on how to do it. These threads can't "outlive" the
request that creates them.
An application can
Implement java.lang.Runnable.
Create a thread factory by calling com.google.appengine.api.ThreadManager.currentRequestThreadFactory().
Call the factory's newRequestThread method, passing in the Runnable, newRequestThread(runnable), or use the factory object
returned by
com.google.appengine.api.ThreadManager.currentRequestThreadFactory()
with an ExecutorService (e.g., call
Executors.newCachedThreadPool(factory)).
However, you must use one of the methods on ThreadManager to create
your threads. You cannot invoke new Thread() yourself or use the
default thread factory.
An application can perform operations against the current thread, such
as thread.interrupt().
Each request is limited to 50 concurrent request threads. The Java
runtime will throw a java.lang.IllegalStateException if you try to
create more than 50 threads in a single request.
When using threads, use high level concurrency objects, such as
Executor and Runnable. Those take care of many of the subtle but
important details of concurrency like Interrupts and scheduling
and bookkeeping.
An elegant way to implement what you need would be to create a parametrable endpoint in your application
/runFeed?db=d1
And from your "main" application code you can perform a fetchAsync call from URLFetchService that will return you a java.util.concurrent.Future<HTTPResponse>
This will allow you a better monitoring of what your application does.
This will add network latency to your application and increase its cost since urlFetchService is not free.

Write to GAE datastore asynchronously

In my Java app, sometimes my users do some work that requires a datastore write, but I don't want to keep the user waiting while the datastore is writing. I want to immediately return a response to the user while the data is stored in the background.
It seems fairly clear that I could do this by using GAE task queues, enqueueing a task to store the data. But I also see that there's an Async datastore API, which seems like it would be much easier than dealing with task queues.
Can I just call AsyncDatastoreService.put() and then return from my servlet? Will that API store my data without keeping my users waiting?
I think you are right that the Async calls seem easier. However, the docs for AsyncDatastore mention one caveat that you should consider:
Note: Exceptions are not thrown until you call the get() method. Calling this method allows you to verify that the asynchronous operation succeeded.
The "get" in that note is being called on the Future object returned by the async call. If you just return from your servlet without ever calling get on the Future object, you might not know for sure whether your put() worked.
With a queued task, you can handle the error cases more explicitly, or just rely on the automatic retries. If all you want to queue is datastore puts, you should be able to create (or find) a utility class that does most of the work for you.
Unfortunately, there aren't any really good solutions here. You can enqueue a task, but there's several big problems with that:
Task payloads are limited in size, and that size is smaller than the entity size limit.
Writing a record to the datastore is actually pretty fast, in wall-clock time. A significant part of the cost, too, is serializing the data, which you have to do to add it to the task queue anyway.
By using the task queue, you're creating more eventual consistency - the user may come back and not see their changes applied, because the task has not yet executed. You may also be introducing transaction issues - how do you handle concurrent updates?
If something fails, it could take an arbitrarily long time to apply the user's updates. In such situations, it probably would have been better to simply return an error to the user.
My recommendation would be to use the async API where possible, but to always write to the datastore directly. Note that you need to wait on all your outstanding API calls, as Peter points out, or you won't know if they failed - and if you don't wait on them, the app server will, before returning a response to the user.
If all you need is for the user to have a responsive interface while stuff churns in the back on the db, all you have to do is make an asynchronous call at the client level, aka do some ajax that sends the db write request, changes imemdiatelly the users display, and then upon an ajax request callback update the view with whatever is it you wish.
You can easily add GWT support to you GAE project (either via eclipse plugin or maven gae plugin) and have the time of your life doing asynchronous stuff.

Handling a timeout in EJB3 without using threads

I have the following situation. I have a job that:
May time out after a given amount of time, and if so occurs needs to throw an exception
If it does not time out, will return a result
If this job returns a result, it must be returned as quickly as possible, because performance is very much an issue. Asynchronous solutions are hence off the table, and naturally tying up the system by hammering isn't an option either.
Lastly, the system has to conform to the EJB standard, so AFAIK using ordinary threads is not an option, as this is strictly forbidden.
Our current solution uses a thread that will throw an exception after having existed for a certain amount of time without being interrupted by an external process, but as this clearly breaks the EJB standard, we're trying to solve it with some other means.
Any ideas?
Edited to add: Naturally, a job which has timed out needs to be removed (or interrupted) as well.
Edited to add 2:
This issue doesn't seem to have any solution, because detecting a deadlock seems to be mostly impossible sticking to pure EJB3 standards. Since Enno Shioji's comments below reflect this, I'm setting his suggestion as the correct answer.
This is more like a request for clarification, but it's too long to fit as a comment..
I'm not sure how you are doing it right now, since from what you wrote, just using the request processing thread seems to be the way to go. Like this:
//Some webservice method (synchronous)
public Result process(Blah blah){
try{
return getResult(TimeUnit.SECONDS, 10);
}catch(InterruptedException e){
//No result within 10 seconds!
throw new ServiceUnavailableException("blah");
}
}
I'm not sure why you are creating threads at all. If you are forced to use threads because the getResult method doesn't timeout at all, you would have a thread leak. If it timeouts after a longer time and thus you want to "shortcut" your reply to the user, that would be the only case I'd consider using a thread like I imagine how you are using it. This could result in Threads piling up under load and I'd strive to avoid such situation.
Maybe you can post some code and let us know why you are creating in your service at all?
Also, what's your client interface? Sounds like it's a synchronous webservice or something?
In that case, if I were you I would use a HashedWheelTimer as a singleton... this mechanism should work great with your requirement (here is an implementation). However, this unfortunately seem to conflict with the ban on threading AND the ban on singleton in the EJB spec. In reality though there really isn't a problem if you would do this. See this discussion for example. We have also used the singleton pattern in our EJB app. which used JBoss. However, if this isn't a viable choice then I might look at isolating the processing in its own JVM by defining a new web service (and deploy it in a web-container or something), and call that service from the EJB app. This would however obviously incur performance hit and now you would have another whole new app.
With Bean Managed Transaction, the timeout for the specific transaction can be specified by using UserTransaction interface.
Modify the timeout value that is
associated with transactions started
by the current thread with the begin
method.
void setTransactionTimeout(int seconds) throws SystemException
Transaction will timeout after specified seconds & may not get propagated further. If exception is not thrown implicitly, then can throw it explicitly based on the result.
Will return a result on successful completion within specified time.
Can use it with stateless session beans so there may not be a performance issue.
Its EJB standard so that will not be an issue to implement.
With little-bit work around, it should work fine in the given scenario.
Edit : Also can use server specific properties to manage transaction timeout.
JBoss : At either at class or method level annotation #TransactionTimeout(100) can be applied.
Weblogic : Specifying the parameters in weblogic-ejb-jar.xml
<transaction-descriptor>
<trans-timeout-seconds>100</trans-timeout-seconds>
</transaction-descriptor>
GlassFish : Using the optional cmt-timeout-in-seconds element in sun-ejb-jar.xml
Stick the process and it's timeout thread in to a class annotated with #WebService, put that class in to a WAR, then invoke the WebService from your EJB.
WARs don't have the same limitations or live under the same contract that EJBs do, so they can safely run threads.
Yes, I consider this a "hack", but it meets the letter of the requirements, and it's portable.
You can create threads using the commonj WorkManager. There are implementations built into WebSphere and Weblogic as they proposed the standard, but you can also find implementations for other appservers as well.
Basically, the WorkManager allows you to create managed threads inside the container, much like using an Executor in regular Java. Your only other alternative would be to use MDB's, but that would be a 'heavier' solution.
Since I don't know your actual platform, you will have to google commonj with your platform yourself 8-)
Here is a non IBM or Oracle solution.
Note: This is not an actual standard, but it is widely available for different platforms and should suit your purposes nicely.
For EJBs, there is a concept of "Container Managed Transactions". By specifying #TransactionAttribute on your bean, or specific method, the container will create a transaction when ever the method(s) are invoked. If the execution of the code takes longer than the transaction threshold, the container will throw an exception. If the call finishes under the transaction threshold, it will return as usual. You can catch the exception in your calling code and handle it appropriately.
For more on container managed transactions, check out: http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Transaction3.html and http://download.oracle.com/javaee/5/tutorial/doc/bncij.html
You could use #TimeOut. Something like:
#Stateless
public class TimedBean {
#Resource
private TimerService timerService;
static private AtomicInteger counter = new AtomicInteger(0);
static private Map<Integer, AtomicBoolean> canIRunStore = new ...;
public void doSomething() {
Integer myId = counter.getAndIncrement();
AtomicBoolean canIRun = new AtomicBoolean(true);
canIRunStore.put(myId, canIRun);
timerService.createTimer(1000, 0, myId);
while (canIRun.get() /* && some other condition */) {
// do my work ... untill timeout ...
}
}
#Timeout
#PermitAll
public void timeout(Timer timer) {
Integer expiredId = (Integer) timer.getInfo();
AtomicBoolean canHeRun = canIRunStore.get(expiredId);
canIRunStore.remove(expiredId);
canHeRun.set(false);
}
}

Need an elegant way to invoke arbitrary code on a specified interval

Ok, I have a game server running in Java/Hibernate/Spring/Quartz. The game clock ticks with a Quartz timer, and that works just fine.
However, I have many other things that need to happen at specific, tweakable intervals (in game time, not real time).
For instance, every 24 hours game time (~ 47 minutes real time, depending on the servers clock multiplier) a bunch of different once-a-day game actions happen, like resupply, or what have you.
Now, the current system is pretty rough, but works - I have a table in the database that's essentially a cron - a string key, the execution time of the next event and then hours, minutes, seconds and days until the next one after that. The time ticker checks that and then fires off a message with that code (the events string key) in it to a queue, adding the days, minutes, seconds to the current time and setting that as the next execution time.
The message listener is the grody part - it switches on the key and hits one of its methods.
Now I understand that this can work just fine, but it really doesn't sit well with me. What would your solution be to this, to have each piece of code in its own little class? What design pattern covers this? (I'm sure there is one). I have a few ideas, but I'd like to hear some opinions.
Rather than a switching on a set of codes, you could use the code as a key into a map, where the values are objects that implement a handler interface. This allows you to be much more flexible in adding new event types.
The pattern looks something like this:
private final Map<String, Handler> handlers = new TreeMap<String, Handler>();
public void register(String event, Handler handler) {
handlers.put(event, handler);
}
public void handle(String event) {
Handler handler = handler.get(event);
if (handler == null) {
/* Log or throw an exception for unknown event type. */
}
else {
handler.execute();
}
}
Rather than explicitly registering handlers, you could use something like Java 6's ServiceLoader to add new behaviors just by dropping JARs into the class path.
I would use a variant of the Command Pattern. I would extend the Command pattern to make a IIntervalCommand class. It would have a interval property, and a readonly CanExecute property in addition to the Execute method.
Then you create a CommandList Class that holds a list of IIntervalCommands. It would have a method called CheckToExecute that you pass it the current game time. The CheckToExecute method would traverse the list calling CanExecute for each command. CanExecute will return true if the elapsed time has occurred. If CanExecute return true then CheckToExecute will call the Execute Method of the object implementing IIntervalCommand.
Then adding additional game events is a matter of creating a new class implementing IIntervalClass. Instantiating the Object and adding it to the IntervalCommandList.
If the processing of the event is time consuming then the command could spawn the processing as a separate thread. It will return false to it's CanExecute property until the thread returns even if the interval has passed again. Or you have it spawn off another thread if the interval passed again.
You avoid the giant case statement. You could eliminate the database and setup the parameters when you instantiate the objects. Or keep it and use it as part of a factory that creates all your IIntervalCommands.
Instead of switching on the key you can use a hashtable to dispatch these events. This way your timer events don't need to know about each other.
It should be possible do have something like:
timerQueue.registerHandler("key",new TimerHandler(){
// do something timer related
});
This way you can restart java code handling events without losing your persisted queue of events.
http://en.wikipedia.org/wiki/Priority_queue'>Priority queues are worth looking at if you have not already.
I personally wouldn't put this in the database but rather keep a separate service running in the background. Then my webservice or web application would communicate with this service through interprocess communication. Don't know how this translates into java world though.
Conceptually I think you're doing two things;
Firstly you have a scaled version of time. As long as the relationship between this time and wall-clock time remains constant I'm fairly sure I'd just delegate this scaling behavior to a single class, that would have signatures like
DateTime getFutureTime( VirtualTimeSpan timespan)
I'd be using this to map virtual time spans to instances of real-time. Thereafter you can operate in real-time, which probably simplifies things a little since you can the use standard scheduling features.
The second part regards scheduling work for a future worker process. There's a number of core technologies working with this; Conceptually I think JMS is the java-grand-dad of a lot of these, it defines concepts much like the ones you're using and what you need. I think taking a look at JMS is fine for seeing concepts you may find interesting, it uses selectors to send tasks to specific workers, much like the ones you decribe.
Alas, JMS never seemed to fit the bill for most people. A lot of people found it was too heavyweight or the implementations too buggy. So usually people ended up with home made queue technologies. But the concepts are all there. Can't you just use quartz ?

Categories

Resources