I'm working with Java RMI. The problem is that, by closing a thread, or call System.exit(0), I need the object registered with the RMI registry to execute an unbind() to remove all associations with the object. When we perform System.exit(0), the object is already registered with the RMI registry.
How I can do so by calling System.exit(0) the unbind() is made of the object in particular? I had thought about making a System.exit() override , but apparently that's not the solution.
The problem is that, by closing a thread, or call System.exit(0), I need the object registered with the RMI registry to execute an unbind() to remove all associations with the object.
So do that. But there is no such thing as 'closing a thread', and even exiting a thread doesn't require you to unbind anything.
When we perform System.exit(0), the object is already registered with the RMI registry.
Good, so the unbind() will succeed. Not sure what point is being made her. Did you mean 'still registered'?
How I can do so by calling System.exit(0) the unbind() is made of the object in particular?
You can't. You have to precede the System.exit() call with an unbind() call.
I had thought about making a System.exit() override , but apparently that's not the solution.
You can't override static methods, and System is final.
It seems you may have System.exit() spattered all over the place, which is already poor practice.
The simple answer is not to call System.exit() at all, but to unbind and unexport the object instead. Then the RMI threads will exit and your JVM will exit of its own accord, as long as you don't have any non-daemon threads of your own.
Related
I've read a few forum posts that some people prefer to use raise event over rpc,
but I can't find the reason why they prefer it. Is raise event interchangeable with rpc?
I mean I get it raise event is easier to use than RPC , because RPC requires the gameobject holding it to have photon view. But is there a situation where I should be using rpc instead of raise event? Any input is greatly appreciated !
RPCs and Events are very similar, but have some key similarities/differences:
Both:
Have options for buffering: (RpcTarget.*Buffered and RaiseEventOptions.CachingOptions)
Have options for encryption: (RpcSecure and SendOptions.Encrypt)
Have options for targeting specific users: (RpcTarget and RaiseEventOptions.Receivers)
Only RPC(s):
Require the [PunRPC] method attribute
Require (and run) on a particular object with a PhotonView
if the object no longer exists on the remote, the RPC never runs and is dropped
Have parameters defined by the method declaration only
Does support method overloading, but not optional parameters
Can have PhotonMessageInfo parameter
Only RaiseEvent(s):
Are always sent "ViaServer"
Your local client will be sent a copy of the event through the server, rather than executing locally immediately (assuming you're a receiver)
Can be circumvented by calling your OnEvent method directly, and using ReceiverGroup.Others
Uses a callback target defining the OnEvent method
Can be called without the need for a target PhotonView
Parameters arbitrary defined, they must be manually parsed/casted by the client
Have a limit of user-definable IDs: 1-200 (can be circumvented with parameters as sub-IDs)
Can be sent both reliably and unreliably via SendOptions
TL;DR: Generally, you'll want to use an RPC if something is related to a PhotonView, and a RaiseEvent call if not. They have basically the same capabilities otherwise
Source: Photon PUN Documentation: "RPCs and RaiseEvent"
When my connection is open, the application won't exit, this causes some nasty problems for me (highly concurrent and nested using a shared sesssion, don't know when each part is finished) - is there a way to make sure that the cluster doesn't "hang" the application?
For example here:
object ZombieTest extends App {
val session= Cluster.builder().addContactPoint("localhost").build().connect()
// app doesn't exit unless doing:
session.getCluster.close() // won't exit unless this is called
}
In a slightly biased answer, you could look at https://github.com/outworkers/phantom instead of using the standard java driver.
You get scala.concurrent.Future, monix.eval.Task or even com.twitter.util.Future from a query automatically. You can choose between all three.
DB connection pools are better isolated inside ContactPoint and Database abstraction layers, which have shutdown methods you can easily wire in to your app lifecycle.
It's far faster than the Java driver, as the serialization an de-serialisation of types is wired in compile time via more advanced macro mechanisms.
The short answer is that you need to have a lifecycle way of calling session.close or session.closeAsync when you shut down everything else, it's how it's designed to work.
I am using com.google.common.util.concurrent.SimpleTimeLimiter,
wondering if this takes care of threadpool shutdown ? I am constructing this using noargs constructor new SimpleTimeLimiter() , but this does not provide a way to call shutdown().
Notice the JavaDoc of ExecutorService.shutdown()
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted. Invocation has no
additional effect if already shut down.
The backing ExecutorService.submit(callable) will be called ONCE inside of SimpleTimeLimiter. Since NO other new tasks will be submitted any more, so shutdown() is not needed.
But if we use constructor SimpleTimeLimiter(ExecutorService executor), then we have to be responsible for shutdown().
So I'm writing a mini timeout library in scala, it looks very similar to the code here: How do I get hold of exceptions thrown in a Scala Future?
The function I execute is either going to complete successfully, or block forever, so I need to make sure that on a timeout the executing thread is cancelled.
Thus my question is: On a timeout, does awaitAll terminate the underlying actor, or just let it keep running forever?
One alternative that I'm considering is to use the java Future library to do this as there is an explicit cancel() method one can call.
[Disclaimer - I'm new to Scala actors myself]
As I read it, scala.actors.Futures.awaitAll waits until the list of futures are all resolved OR until the timeout. It will not Future.cancel, Thread.interrupt, or otherwise attempt to terminate a Future; you get to come back later and wait some more.
The Future.cancel may be suitable, however be aware that your code may need to participate in effecting the cancel operation - it doesn't necessarily come for free. Future.cancel cancels a task that is scheduled, but not yet started. It interrupts a running thread [setting a flag that can be checked]... which may or may not acknowledge the interrupt. Review Thread.interrupt and Thread.isInterrupted(). Your long-running task would normally check to see if it's being interrupted (your code), and self-terminate. Various methods (i.e. Thread.sleep, Object.wait and others) respond to the interrupt by throwing InterruptedException. You need to review & understand that mechanism to ensure your code will meet your needs within those constraints. See this.
While writing Scala RemoteActor code, I noticed some pitfalls:
RemoteActor.classLoader = getClass().getClassLoader() has to be set in order to avoid "java.lang.ClassNotFoundException"
link doesn't always work due to "a race condition for which a NetKernel (the facility responsible for forwarding messages remotely) that backs a remote actor can close before the remote actor's proxy (more specifically, proxy delegate) has had a chance to send a message remotely indicating the local exit." (Stephan Tu)
RemoteActor.select doesn't always return the same delegate (RemoteActor.select - result deterministic?)
Sending a delegate over the network prevents the application to quit normally (RemoteActor unregister actor)
Remote Actors won't terminate if RemoteActor.alive() and RemoteActor.register() are used outside act. (See the answer of Magnus)
Are there any other pitfalls a programmer should be aware of?
Here's another; you need to put your RemoteActor.alive() and RemoteActor.register() calls inside your act method when you define your actor or the actor won't terminate when you call exit(); see How do I kill a RemoteActor?