Running actor manually? - scala

I'm working on my first Play Framework 2 application. I want to call a web service every once in a while and store data in the database so I've started writing an actor that is scheduled to every hour.
Problem is, I'm wasting a lot of time simply waiting for the job to be triggered (even if I've scheduled to be ran every minute while I'm testing. I'd love to be able to start the import manually, simply to make sure it works.
I've tried using the scala console, but it doesn't automatically reload my code every time I save so I have to restart the console manually. I've considered wrapping the import process in a class and use unit testing and mocking but I'm looking for a quicker way, especially because I'm new to Play and Scala.
Any idea or suggestion?
Thanks!

How about writing a custom sbt task?
A simple way to write an sbt task that loads your application class path, so you can implement the behavior with a method call in your application code, can be found at sbt-tasks.

I'm assuming you are using the Akka scheduler inside the Actor to trigger a message to itself which then invokes web service. You can just send same message (ActorRef ! Message) to the actor while you are doing your testing.

Related

Recurring function at date/time

I'm trying to call a function when my macOS application is in any state, including terminated. Here is what i'm trying to accomplish:
Schedule a function (much like DispatchQueue.main.asyncAfter()) to run daily at a given time (let's say 9AM). I would like to add a feature to my application that allows a user to pick a time of day, and have an Alamofire POST request run at that time every day.
I have tried using a Runloop, and more recently Grand Central Dispatch:
DispatchQueue.main.asyncAfter(wallDeadline: DispatchWallTime.now() + .seconds(60)) {
//Alamofire
}
I can easily accomplish this while the application is running with a timer, but have yet to find a way to accomplish this in the background, with the app running.
This may be pretty heavy to implement (i.e. not straightforward), but if you want a task to run even if your app is terminated, you might need to consider writing your own LaunchAgent.
The trick here would be for the agent to be able to interact with your application (retrieving or sending shared information).

Service Fabric long running process

I have a Web Api stateless service that is creating an Actor that does some long running processing via a reminder (fire and forget). It stores its own progress in local state. I am unable to get the progress of that long running process due to the single threaded nature of the Actor, any call to the method that gets the progress will wait until the long running process has completed. Does anyone have a solution for this (without using an external data source)?
If you simply wish to get the current state of your Actor without having to wait for an Actor lock you can actually use the underlying ActorService that is hosting the Actors to query the state without interrupting, or being blocked by the long running Actor method.
The ActorService hosting Actors is really just a StatelessService (with some bells and whistles) and you can communicate with it the same way you would communicate with any Service - add an IService interface to it and the use IServiceProxy to talk to it. This SO Answer shows how you can do that How to get state from service fabric actor without waiting for other methods to complete?
If you want to get progress along the way even during the execution of your Actor method you can force a save of the state changes in the middle of your long running exectuion by calling SaveStateAsync
You could create a ProgressTrackingActor and periodically update it from the existing Actor. Query the ProgressTrackingActor for progress.
You can use an ActorReference to indicate which Actor to query progress for, or use the same ActorId value.

Stopping the execution of a currently running job after some time

I am using quartz to schedule jobs to be executed daily as a part of a much larger web application. However, after a couple of days, the administrator would like to stop the execution of a particular job (maybe because it is no longer needed). How do I go about doing this? I read the api docs for the Scheduler and it has a method called interrupt(JobKey jobkey) but that method would work only with the same instance of the scheduler that was used to schedule the job.
interrupt(JobKey jobKey)
Request the interruption, within this Scheduler instance, of all
currently executing instances of the identified Job, which must be an
implementor of the InterruptableJob interface.
Is there anyway of getting the instance of an existing scheduler? Or maybe use singletons?
Should definitely use a singleton instance of your scheduler. I recommend the use of an IoC container to manage this in a clean and efficient way.

Batch processing with celery?

I am using celery to process and deploy some data and I would like to be able to send this data in batches.
I found this:
http://docs.celeryproject.org/en/latest/reference/celery.contrib.batches.html
But I am having problems with it, such as:
It does not play nicely with eventlets, putting exceptions in the log
files stating that the timer is null after the queue is empty.
It seems to leave additional hanging threads after calling celery
multi stop
It does not appear to adhere to the standard logging of a typical
Task.
It does not appear to retry the task when raise mytask.retry() is
called.
I am wondering if others have experienced these problems, and is there a solution?
I am fine with implementing batch processing on my own, but I do not know a good strategy to make sure that all items are deployed (i.e. even those at the end of the thread).
Also, if the batch fails, I would want to retry the entire batch. I am not sure of any elegant way to do that.
Basically, I am looking for any viable solution for doing real batch processing with celery.
I am using Celery v3.0.21
Thanks!

What's the best way to handle initialization errors in Play! Framework 2.0?

Imagine I have an application written using Play 2. Imagine that application needs to grab hold of some things on startup (read a config file, grab some resources from JNDI, that kind of thing). Play handily gives us the GlobalSettings object that we can use to hook into start and stop events:
import play.api._
object Global extends GlobalSettings {
var someResource: Resource = _
override def onStart(app: Application) {
// might throw an exception if the path doesn't exist
resource = JNDI.grabThing("/some/path").asInstanceOf[Resource]
}
}
The problem is - what can we do if the initialisation fails? It seems that this is only executed when Play receives the first request for the application. If we throw an exception, that causes that request to fail, but the application keeps on running.
Ideally, what I'd like is to stop the application from starting at all if this block doesn't complete successfully. Unfortunately, calling Play.stop() doesn't actually seem to, well, stop Play. I can see that the Server trait defines def stop(), which looks promising but I can't figure out a way to get hold of the Server instance from inside my application.
Perhaps I'm looking at this the wrong way, and I'm not supposed to be able to stop Play (or even just my app) from inside my application, so suggestions for other approaches are welcome.
What's the best way to handle these errors?
It seems I'm lying. Play only continues to serve requests after an exception in onStart if you're running in dev mode (play run). If started with play start (i.e. production mode) an exception here will terminate the server, which is exactly what I wanted.
It does appear to leave the RUNNING_PID file lying around, which is irritating, but that's a separate issue...