Overview

When developing applications, it is often a requirement only a single instance is active on the system at one time (thus it is called an "application singleton"). NOTUVY SingleApp is a framework that provides this functionality. It is small an easy to integrate, and quickly provides this useful feature.

Consider the simple case of a text editor. (This is not really a pertinent example, but it illustrates the general issue.) If a user opens two instances of a text editor on the same document, it could lead to potential problems. If a change is made to one, then the the contents of the other (assuming it does not have an auto-refresh capability) are out of date and inconsistent. One way to avoid this to never allow more than one instance of the editor to launch.

The concept of a Singleton is a standard design pattern. It is easy to apply it to classes within an application. But applying it to applications on a host is much more complicated. This issue is solved by using notuvysingleapp. Using notuvysingleapp will quickly and easily add this behavior to your application.

Features

User Scope

The more common case is where the desired restriction is to allow only one instance of an application for a single user running at any time. But multiple users are allowed to also launch their own instances of the application.

The less common but more simple case is to have maximum one instance of the application allowed system-wide, regardless of user.

Instance Selection Strategies

There are to possible strategies to handle the case of a conflict. Both of these strategies are implemented by notuvysingleapp.

  • Defer

    If a duplicate instance is launched, then it should not be allowed to start. The existing instance gets precedence.

  • Preempt

    If a duplicate instance is launched, then it gets precedence over the existing instance. The existing instance is instructed to gracefully exit and the new instance is allowed to finish starting.

Inter-Instance Messaging

In some cases, it may be desireable for the deferred or preempted instance to transfer information to the surviving instance.

Consider the example of a web browser using the defer strategy. If one instance of the browser is already alive and another is attempted by the user, then before the deferred instance dies, it could send the surviving instance the URL that the user wanted to view. That way the previous instance can display that page and the user's intentions are satisfied.

The framework provides an easy mechanism for doing this messaging. For Defer, the non-launching instance sends a message to the existing instance (as demonstrated in the example above). For Preempt, the older (about-to-die) instance sends a message to the new instance before the former gracefully exits. That way the new (about-to-start) instance gets any state information necessary to continue the work of the instance being replaced.

How it Works

These are the implementation details for the curious.

The framework makes use of interprocess communication using sockets. The living instance listens on a port (which the application programmer chooses). Any new instance will attempt to start the listener. The first instance will always succeed and any after that will detect a port conflict. At this point it enters into the logic of how to resolve the conflict.

The situation is a bit more complicated when allowing multiple users to each start an instance. In that case a system-wide broker is used to manage the port listener. If the process owning the broker terminates, than one of the other living processes will inherit the broker. Each new instance tells the broker which user they are launching on behalf of, and the broker determines if that user already has a running instance.

The use of sockets also allows the interchange of data, which is used for inter-instance messaging as described above.