Dropwizard Shutdown Hook - java

The problem is, that I stop Dropwizard application (via ctrl + c) and I have inserted a Shutdown Hook in main class to do some stuff before shutdown. But now ServerConnector for the application is closed before I can do what I want to do.
There is a polling service (polls one of my resources) and I need to tell them, that application will go down soon to prevent some problems. I need at least 15 seconds before ressource goes down.
Some idea how to solve this problem?

You can use a lifecycle hook to manage certain resources.
public class ManagedObject implements Managed {
private final Object obj;
public ManagedObject(Object obj) {
this.obj = obj;
}
#Override
public void start() throws Exception {
// Do something to start the object
}
#Override
public void stop() throws Exception {
// Do something to stop the object
}
}
Then register on the environment
ManagedObject myManagedObject = new ManagedObject(obj);
environment.lifecycle().manage(myManagedObject);

Add a Dropwizard Task that will change the state of a static field (or however you want to pass the data) which your polling resource will be using to respond.
public class ShutdownTask extends Task {
private int timeoutSeconds;
public ShutdownTask (int timeoutSeconds) {
super("shutdown");
this.timeoutSeconds = timeoutSeconds;
}
#Override
public void execute(ImmutableMultimap<String, String> parameters, PrintWriter output) throws Exception {
// you probably can take the timeout parameter from the request via 'parameters' instead of the constructor.
PollingResource.shuttingDownIn = timeoutSeconds;
}
}
environment.admin().addTask(new ShutdownTask(15));
Then write a bash script which will curl to task
curl -X POST http://dw.example.com:8081/tasks/shutdown
And:
This is probably not recommended (people don't like System.exit(0)) but you can add the following to execute method:
Thread.sleep(timeoutSeconds * 1000);
System.exit(0)
Or do the waiting and kill the dropwizard app in the bash script.
kill -SIGINT <pid>

Related

Cordova Plugin - Java: wait for callback

I have a plugin method that acts on remote hardware via Bluetooth.
It sends a command to the hardware, which executes some action.
After the hardware action finishes a callback defined outside of my method is called.
I only want to call CallbackContext.success(...) or CallbackContext.error(...) after the callback is called, so i want to wait for my callback to be called.
How would i go about this?
E.g. part of CordovaPlugin-class:
public void actOnHardware(CallbackContext callbackContext)
{
this.verifiyBluetoothEnabled();
this.hardwareConnection.doSomething()
// Now wait for the callback to complete before calling
// callbackContext.success() or error()
callbackContext.error("Not implemented.");
}
#Override
public void hardwareActionCallback(result)
{
// Notify actOnHardware() that we're finished.
}
This seems to be more of a Java thing, but i can't get my head to wrap around it.
Is using Object.wait() and Object.notify() a viable option or does calling wait() prevent the callback from getting called due to thread stuff? If so - how to solve this?
E.g. is it sufficient to just do:
private Object lockObj;
private boolean actionFinished;
public void actOnHardware(CallbackContext callbackContext)
{
this.verifiyBluetoothEnabled();
this.actionFinished = false;
this.hardwareConnection.doSomething()
while(!this.actionFinished)
this.lockObj.wait();
callbackContext.error("Not implemented.");
}
#Override
public void hardwareActionCallback(result)
{
this.actionFinished = true;
this.lockObj.notify();
}
Kind Regards

Losing ApplicationContext when executing new runnables

I know I'm new to this spring stuff but I've been stuck on this all day. I don't much like asking questions but maybe I'll get an idea.
So here's my problem:
I'm trying to create a Queue for processing stuff on the back end. I did this by creating a static executorservice in a component class with helper methods to run them. it seems to work like i want, and when i wire in classes i can get into those classes, but it seems like when those are running they lose application context (or something this is just my guess).
I'm sure There are better ways to do this, but in the custom framework I am working in there are a number of features that will not work for me. I have no spring-config.xml, cannot use #Configuration
executor service component
#Component
public class FifoComponent {
public static ExecutorService executors = Executors.newSingleThreadExecutor();
private static Lock lock = new ReentrantLock(true);
public static void executeNewTestJob(int i) {
lock.lock();
OrderAllocationTestJob job = new OrderAllocationTestJob(i);
executors.execute(job);
lock.unlock();
}
}
Runnable component - note appdateutils has a method that calls a component that and works fine in my typical tomcat environment
#Component
public class OrderAllocationTestJob implements Runnable {
int i;
public OrderAllocationTestJob(int i) {
this.i = i;
}
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Asynchronous task " + i);
System.out.println(AppDateUtils.getCurrentTimeStamp());
}
}
call from a struts 2 action (test) i know I can call the appdateutils.gettime method from
for (int i = 0; i < 50; i++) {
FifoComponent.executeNewTestJob(i);
}
here's the exception i end up with for what it's worth
"Scope 'request' is not active for the current thread"
Exception in thread "pool-15-thread-50" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dateTimestampDao': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
"I'm sure There are better ways to do this"
Based on this, you'll need to create/lookup all request and session scoped components before call another thread. Actually, request injection is thread local and can't works in your scenario.
i think if u remove
Thread.sleep(100);
in OrderAllocationTestJob to
job.sleep(100);
in FifoComponent will fix your problem
I solved this solution by extending ConcurrentLinkedQueue for my runnables and keeping them in a manager I instantiated in the initialize method of a ServletContextListener. By overriding the offer() method of the ConcurrentLinkedQueue to continually poll until the queue was empty I was able synchronously process runnables.
Unfortunately this locks down the request thread until the runnable is done and I will have to have my users keep an eye on it and let me know if the pages end up running long, but at least in my test environment the process seems sub-second even when i hit it with 20 at a time so I'm OK for now.
I would still prefer an ExecutorService executed from my Tomcat container but outside the scope of the requests but unless someone can answer the question I'm just going to have to leave it for now
Are you looking something like that?
#Component
public class AsynchronousThread extends Thread {
public static final Logger LOGGER = LoggerFactory
.getLogger(AsynchronousThread.class);
#Autowired
private Writer writer;
private BlockingQueue<IndexContextDTO> blockingQueue = new LinkedBlockingQueue<IndexContextDTO>(
500);
/**
*
*/
public AsynchronousThread() {
super("AsynchronousThread");
}
#PostConstruct
public void init() {
Integer internalQueueSize = 100;
this.blockingQueue = new LinkedBlockingQueue<>(internalQueueSize);
this.start();
}
#Override
public void run() {
while (true) {
// Do stuff
}
}
public void putInQueue(IndexContextDTO message) {
try {
this.blockingQueue.put(message);
} catch (InterruptedException interruptedException) {
// This exception will be thrown in very rare case.
LOGGER.error("An error while putting message in the queue. "
+ message, interruptedException);
}
}
}

Initializing time intensive subsystem in Websocket application

I am creating a websocket application, and I want to perform a one-time time intensive task at program initialization. In creating this application, the recommended practice (https://netbeans.org/kb/docs/javaee/maven-websocketapi.html) is to override the following functions:
#ServerEndpoint(value = "/testendpoint", encoders = {TestEncoder.class}, decoders = {TestDecoder.class})
public class WSEndpoint
{
#OnMessage
public void onMessage(Session wsSession, CommandIn command) throws IOException, EncodeException
{
...
}
#OnOpen
public void onOpen(Session wsSession)
{
...
}
#OnClose
public void onClose(Session wsSession)
{
...
}
#OnError
public void onError(Throwable t)
{
}
}
So when a new connection/session is created, "onOpen" would be called and when a new message is received, "onMessage" is called.
What I want to do is, before letting the user create sessions and send commands (via browser front end), to initialize the subsystem that takes about 20 seconds to initialize. If it's initialized only at "first requested use", as I am doing now, then the user experience gets interrupted. Clearly, there is no "main" function visible here (presumably, called by the websocket framework at a deeper level).
What do you guys recommend I do to achieve what I want to do? Currently, I have the initialization code in a static block in an internal class - which only gets executed once - but gets executed when the class is first "called/used", interrupting the user experience.
Any suggestions?
Thanks.
The best place for initialization code in a web application is inside a ServletContextListener's contextInitialized method.
This way you do your initialization when the application starts.

RMI Threads prevent JVM from exiting after main() completes

To make a long story short, I'm having trouble getting a couple of Java RMI's non-daemon threads to close out after my application no longer needs RMI. This prevents the JVM from exiting when main() completes.
I understand that exporting UnicastRemoteObjects will cause RMI to leave threads open until you successfully call UnicastRemoteObject.unexportObject(Object o,boolean force). Here's an example (run without modification and the JVM will exit normally - remove the call to unexportObject and the JVM will never exit):
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class TestUnicastRemoteObject{
private static UnicastRemoteObject obj;
private static Registry registry;
public static void main(String[] args) throws Exception{
obj = new UnicastRemoteObject(){
private static final long serialVersionUID = 1L;
};
System.err.println("created UnicastRemoteObject");
System.err.println("creating registry ...");
registry = LocateRegistry.createRegistry(9999);
System.err.println("registry created.");
System.err.println("binding obj to registry ...");
registry.bind("Test", obj);
System.err.println("bound");
UnicastRemoteObject.unexportObject(obj, true);
System.err.println("unexported obj");
}
}
Also, it doesn't seem to matter whether you create the registry and/or bind the remote object to it - the only thing that seems to matter in this example is that any time you create a UnicastRemoteObject, you need to call unexportObject in order to prevent any threads from remaining after you're done.
In my application, I've made sure that I've called unexportObject on every UnicastRemoteObject I create, and yet RMI's "reaper" thread and "connection accept" thread still persist, preventing my JVM from exiting when my application is finished using RMI resources.
Is there something else that could cause RMI to leave threads behind, aside from forgetting to unexport UnicastRemoteObjects?
Sure enough, I had a bug in the code that caused one of my (many) UnicastRemoteObjects to not unexport itself when the calling application was done utilizing it. So the answer is:
Unexporting all UnicastRemoteObjects within a running JVM is sufficient to close all RMI non-daemon threads.
Sounds like you solved you problem #Ben but for posterity, I thought I'd promote my comment to an answer. Whenever I have a register/unregister type of pattern I make sure to manage them through a singleton object. This way you have one place to go to figure out which object was not unregistered. Exposing this in JMX is also a win.
Something like the following code would be good. It will allow you to log or JMX query to see what objects have been bound to the registry but have yet to be unbound.
public class UnicastRegistry {
private static Registry registry;
private static UnicastRegistry singleton;
// private to force the singleton
private UnicastRegistry() throws RemoteException {
registry = LocateRegistry.createRegistry(9977);
}
public static UnicastRegistry createSingleton() throws RemoteException {
if (singleton == null) {
singleton = new UnicastRegistry();
}
return singleton;
}
public void register(String label, Remote obj) throws Exception {
registry.bind(label, obj);
}
public void unregister(String label) throws Exception {
Remote remote = registry.lookup(label);
registry.unbind(label);
if (remote instanceof UnicastRemoteObject) {
UnicastRemoteObject.unexportObject(remote, true);
}
}
public void unregisterAll() throws Exception {
for (String label : registry.list()) {
unregister(label);
}
}
public void printStillBound() throws Exception {
String[] stillBound = registry.list();
if (stillBound.length > 0) {
System.out.println("Still bound = " + Arrays.toString(stillBound));
}
}
}

Process Monitoring in GWT

Does anyone know how to monitor long-running server-side processes in GWT, other than polling the server? We need to do some time-consuming, multiple-step, I/O-bound processing on the server, and it would be nice to display the progress of this processing in the browser.
This is fairly easy to handle in GWT.
The long-running process is either triggered by a GWT RPC call, in which case you have your entry point, or it isn't, in which case you need to start this off manually.
Remember that GWT RPC calls are asynchronous so they don't need to return immediately. You need an RPC call like checkStatus(). So you can do things like:
public class JobStatus {
private boolean done;
// other info
// ...
}
public class JobStatusCallback<JobStatus> extends AsyncCallback {
public final void onSuccess(JobStatus result) {
if (result.isDone()) {
done();
} else {
checkAgain();
}
}
public final void onFailure(Throwable caught) {
error(caught);
checkAgain();
}
public void done() { // override
}
public void checkAgain() {
service.checkStatus(this);
}
public void error(Thorwable t) { // override
}
});
and in your RPC service:
void checkStatus(AsyncCallback<JobStatus> callback);
Your server can take as long as it likes (within reason) to return from checkStatus(). It can return because the job is done or just with a job status update. The above will continue looping until the job status done flag is set.
I think it depends on your process but if you are going to do something like Data Streaming you can use Server Push (Or Comet) technic.GWT supports Comet implementation.
google GWT+Comet ,or GWT+COMET+Tomcat,i read about comet and gwt in "Google Web Toolkit Applications" Book(gwtapps.com).

Categories

Resources