package eu.fbk.knowledgestore.runtime; import java.io.Closeable; import java.io.IOException; /** * A KnowledgeStore internal component. * <p> * This interface defines the basic API and lifecycle of a generic KnowledgeStore internal * component, and is specialized for specific types of components. * </p> * <p> * The <i>lifecycle</i> of a {@code Component} is the following: * <ul> * <li>The {@code Component} instance is created starting with a number of key/value properties * and using one of the mechanisms supported by {@link Factory} (i.e., constructor, static factory * method, builder pattern). The {@code Component} instance configures itself based on the * supplied properties. In case the configuration is incorrect, an exception will be thrown; * otherwise, the component is now configured, but still inactive, meaning that no activity is * being carried out by the component, no persistent data is being modified and no resource that * needs to be later freed is being allocated.</li> * <li>Method {@link #init()} is called to initialize the {@code Component} instance and make it * operational; differently from the constructor, method {@code init()} is allowed to allocate any * resource, to modify persisted data and to start any task as necessary for the component to * perform its tasks.</li> * <li>Methods in the {@code Component} interface are called by external code (e.g., the * frontend). Whether these methods can be called by a thread at a time (meaning the component can * be thread-unsafe) or concurrently by multiple threads (meaning the component must be * thread-safe) depends on the particular type of component, as documented in itsJavadoc.</li> * <li>Method {@link #close()} is called to dispose the {@code Component} object, allowing it to * free allocated resources (e.g., close files and network connections) in an orderly way. Note * that method {@code close()} can be called at any time after the component has been instantiated * (even before initialization, in case external failure requires the component to be immediately * disposed). In particular, it is possible for the {@code close()} method to be called while a * component method is being invoked by another thread.</li> * </ul> * </p> * <p> * Components are expected to access external resources (e.g., storage) or to communicate to * external processes, hence methods in this interface and its specializations may throw * {@link IOException}s. As a special kind of <tt>IOException</tt>, they may throw a * {@link DataCorruptedException} in case a data corruption situation is detected, possibly * triggering some external recovery procedure. * </p> */ public interface Component extends Closeable { /** * Initializes the {@code Component} with the supplied {@code Runtime} object. This method is * called after the instantiation of a {@code Component} and before any other instance method * is called. It provides a {@code Runtime} that can be used to access runtime services such * as locking, serialization and filesystem access. The {@code Component} is allowed to * perform any initialization operation that is necessary in order to become functional; on * failure, these operations may result in a {@link IOException} being thrown. * * @throws IOException * in case initialization fails * @throws IllegalStateException * in case the component has already been initialized or closed */ void init() throws IOException, IllegalStateException; /** * Closes this {@code Component} object. If the component has been initialized, closing a it * causes any allocated resource to be freed and any operation or transaction ongoing within * the component being aborted; in case the component has not been initialized yet, or * {@code close()} has already being called, calling this method has no effect. Note that the * operation affects only the local {@code Component} object and not any remote service this * object may rely on to implement its functionalities; in particular, such a remote service * is not shutdown by the operation, so that it can be accessed by other {@code Component} * instances possibly running in other (virtual) machines. Similarly, closing a * {@code Component} object has no impact on stored data, that continues to be persisted and * will be accessed unchanged (provided no external modification occurs) the next time a * similarly configured {@code Component} is created. */ @Override void close(); }