* New interface for clients started via clients.config, and a new

manager to track the lifecycle and start/stop clients on demand.
    Not hooked in to console yet, untested.
    (ticket #347)
This commit is contained in:
zzz
2012-10-13 12:45:08 +00:00
parent 6f509967bf
commit d198ae9ef1
9 changed files with 407 additions and 11 deletions

View File

@ -0,0 +1,58 @@
package net.i2p.app;
import net.i2p.I2PAppContext;
/**
* If a class started via clients.config implements this interface,
* it will be used to manage the client, instead of starting with main()
*
* Clients implementing this interface MUST provide the following constructor:
*
* public MyClientApp(I2PAppContext context, ClientAppManager listener, String[] args) {...}
*
* All parameters are non-null.
* This constructor is for instantiation only.
* Do not take a long time. Do not block. Never start threads or processes in it.
* The ClientAppState of the returned object must be INITIALIZED,
* or else throw something.
* The startup() method will be called next.
*
* Never ever hold a static reference to the context or anything derived from it.
*
* @since 0.9.4
*/
public interface ClientApp {
/**
* Do not take a long time. Do not block. Start threads here if necessary.
* Client must call ClientAppManager.notify() at least once within this
* method to change the state from INITIALIZED to something else.
* Will not be called multiple times on the same object.
*/
public void startup() throws Throwable;
/**
* Do not take a long time. Do not block. Use a thread if necessary.
* If previously running, client must call ClientAppManager.notify() at least once within this
* method to change the state to STOPPING or STOPPED.
* May be called multiple times on the same object, in any state.
*/
public void shutdown(String[] args) throws Throwable;
/**
* The current state of the ClientApp.
*/
public ClientAppState getState();
/**
* The generic name of the ClientApp, used for registration,
* e.g. "console". Do not translate.
*/
public String getName();
/**
* The dislplay name of the ClientApp, used in user interfaces.
* The app must translate.
*/
public String getDisplayName();
}

View File

@ -0,0 +1,51 @@
package net.i2p.app;
/**
* Notify the router of events, and provide methods for
* client apps to find each other.
*
* @since 0.9.4
*/
public interface ClientAppManager {
/**
* Must be called on all state transitions except
* from UNINITIALIZED to INITIALIZED.
*
* @param app non-null
* @param state non-null
* @param message may be null
* @param e may be null
*/
public void notify(ClientApp app, ClientAppState state, String message, Exception e);
/**
* Register with the manager under the given name,
* so that other clients may find it.
* Only required for apps used by other apps.
*
* @param app non-null
* @param name non-null
* @return true if successful, false if duplicate name
*/
public boolean register(ClientApp app);
/**
* Unregister with the manager. Name must be the same as that from register().
* Only required for apps used by other apps.
*
* @param app non-null
* @param name non-null
*/
public void unregister(ClientApp app);
/**
* Get a registered app.
* Only used for apps finding other apps.
*
* @param app non-null
* @param name non-null
* @return client app or null
*/
public ClientApp getRegisteredApp(String name);
}

View File

@ -0,0 +1,25 @@
package net.i2p.app;
/**
* Status of a client application.
* ClientAppManager.notify() must be called on all state transitions except
* from UNINITIALIZED to INITIALIZED.
*
* @since 0.9.4
*/
public enum ClientAppState {
/** initial value */
UNINITIALIZED,
/** after constructor is complete */
INITIALIZED,
STARTING,
START_FAILED,
RUNNING,
STOPPING,
/** stopped normally */
STOPPED,
/** stopped abnormally */
CRASHED,
/** forked as a new process, status unknown from now on */
FORKED
}

View File

@ -0,0 +1,18 @@
<html>
<body>
<p>
Interfaces for classes to be started and stopped via clients.config.
Classes implementing the ClientApp interface will be controlled with
the that interface instead of being started with main().
</p>
<p>
The benefits for clients using this interface:
<ul>
<li>Get the current context via the constructor
<li>Complete life cycle management by the router
<li>Avoid the need for static references
<li>Ability to find other clients without using static references
</ul>
</p>
</body>
</html>