Tango V10 Server side design proposal
Below are some ideas that are proposed by this document to be implemented in server side Tango v10 core library.
Internal event bus
Server side library is split into loosely coupled components. Each component interacts with others via internal event bus:
interface EventBus {
void subscribe(String event, Class<T> dataType);
<T> void publish(String event, Message<T> message);//TODO runtime message type check
}
interface Message<T> {
String getEventName();
T getEventData();
}
interface EventBusListener {
void onBeforeEvent();
void onEvent(Object message);
void onError(Exception clause);
void onAfterEvent();
}
TangoEventBus extends EventBus by adding Tango specific server side events:
interface AttributeRead<T extends TangoDeviceAttribute<V>, V extends TangoDataType> {
T getAttribute();
V getData();
}
interface AttributeWrite<T extends TangoDeviceAttribute, V extends TangoDataType> {
T getAttribute();
V getData();
}
interface CommandExecute<T extends TangoDeviceCommand<IN, OUT>, IN extends TangoDataType, OUT extends TangoDataType> {
T getCommand();
IN getInput();
OUT getOutput();
}
interface TangoEventBus extends EventBus {
void attributeRead(Message<AttributeRead> data);
void attributeWrite(Message<AttributeWrite> data);
void commandExecute(Message<CommandExecute> data);
void eventReceived(Message<TangoEvent> data);
}
interface TangoReadAttributeListener {
void onBeforeAttributeRead(Message<AttributeRead> data);
void onAttributeRead(Message<AttributeRead> data);
void onAfterAttributeRead(Message<AttributeRead> data);
}
interface TangoWriteAttributeListener {
void onBeforeAttributeWrite(Message<AttributeWrite> data);
void onAttributeWrite(Message<AttributeWrite> data);
void onAfterAttributeWrite(Message<AttributeWrite> data);
}
interface TangoExecuteCommandListener {
void onBeforeExecuteCommand(Message<CommandExecute> data);
void onExecuteCommand(Message<CommandExecute> data);
void onAfterExecuteCommand(Message<CommandExecute> data);
}
interface TangoEventReceivedListener {
void onBeforeEventReceived(Message<EventReceived> data);
void onEventReceived(Message<EventReceived> data);
void onAfterEventReceived(Message<EventReceived> data);
}
//etc
TangoKernelComponent
Each component receives TangoContext and DeviceContext during initialization:
interface TangoKernelComponent {
void initialize(TangoContext tangoContext, DeviceContext context);
}
interface TangoWorkerComponent extends TangoKernelComponent {
void start();
}
Typical TangoComponentImpl:
class Foo implements TangoKernelComponent, TangoWriteAttributeListener {//TODO generics
//in Java this can be replaced with annotation type, i.e. @TangoComponent or @TangoWorkerComponent
static {
TangoContext.registerComponent(Foo.class);
}
/**
* NOTE: in Java this can be replaced with DependencyInjection aka Guice
*/
@Override
void initialize(TangoContext tangoContext, DeviceContext context){
tangoContext.getEventBus().subscribe("org.tango.read_attribute");
}
void onBeforeAttributeWrite(AttributeWrite<> message){//TODO generics
System.out.printf("Write %d into attribute %s ",message.getData(), message.getAttribute().getName());
}
}
TangoEngineComponent
Central component of the server side API is TangoEngineComponent. This component intiliazes all other components and performs an orchestration of all components i.e. wraps TangoEventBus:
interface TangoEngineComponent extends TangoComponent{
void start();
}
Typical implementation:
class TangoEngineComponentImpl implements TangoEngineComponent {
void initialize(TangoContext context, DeviceContext deviceContext){
context.getRegisteredComponents()
.forEach( (cmpt) -> System.out.println(cmpt.getClass().getSimpleName()));
}
void start(){
context.getRegisteredWorkerComponents()
.forEach( (cmpt) -> cmpt.start());
}
}
AttributeReadComponent
AttributeWriteComponent
EventSystemComponent
PollingComponent
LoggingComponent
Tango V10 Client side design proposal
interface TangoHost {
String getHostName();
String getIP();
int getPort();
}
interface TangoDeviceName {
/**
* @return fullName + modifiers e.g. tango:<udp>://<tangohost>:<tangoport>/<domain>/<family>/<member>?no_db=true
*/
String getRawName();
/**
* @return full name e.g. tango:<udp>://<tangohost>:<tangoport>/<domain>/<family>/<member>
*/
String getFullName();
String getProtocol();
TangoHost getTangoHost();
String getName();
MultiMap<String,String> getModifiers();
}
The rest is moved to src/main/java/org/tango/v10