diff --git a/legacyworlds-server-beans-events/src/main/java/com/deepclone/lw/beans/events/EventProcessorBean.java b/legacyworlds-server-beans-events/src/main/java/com/deepclone/lw/beans/events/EventProcessorBean.java new file mode 100644 index 0000000..54a9154 --- /dev/null +++ b/legacyworlds-server-beans-events/src/main/java/com/deepclone/lw/beans/events/EventProcessorBean.java @@ -0,0 +1,113 @@ +package com.deepclone.lw.beans.events; + + +import javax.sql.DataSource; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +import com.deepclone.lw.interfaces.sys.Ticker; +import com.deepclone.lw.interfaces.sys.Ticker.Frequency; + + + +/** + * Events processor component + * + *
+ * This component acquires the necessary dependencies to create an {@link EventProcessorTask}, does + * so, and registers it with the ticker. It clears the reference to the task when destroyed. + * + * @author E. Benoît + * + */ +class EventProcessorBean + implements InitializingBean , DisposableBean +{ + + /** The ticker */ + private Ticker ticker; + + /** The Spring transaction template */ + private TransactionTemplate tTemplate; + + /** The database interface */ + private DataSource dataSource; + + /** The task */ + private Runnable task; + + + /** + * Dependency injector that sets the ticker component + * + * @param ticker + * the ticker component + */ + @Autowired( required = true ) + public void setTicker( Ticker ticker ) + { + this.ticker = ticker; + } + + + /** + * Dependency injector that sets the transaction manager + * + *
+ * Creates the transaction template from the transaction manager + * + * @param tManager + * the Spring transaction manager + */ + @Autowired( required = true ) + public void setTransactionManager( PlatformTransactionManager tManager ) + { + this.tTemplate = new TransactionTemplate( tManager ); + } + + + /** + * Dependency injector that sets the database interface + * + * @param dataSource + * the database interface + */ + @Autowired( required = true ) + public void setDataSource( DataSource dataSource ) + { + this.dataSource = dataSource; + } + + + /** + * Initialise and register the event processing task + * + *
+ * When the component's dependencies have been injected, this method creates the + * {@link EventProcessorTask} instance and registers it to the ticker. + */ + @Override + public void afterPropertiesSet( ) + { + this.task = new EventProcessorTask( this.tTemplate , this.dataSource ); + this.ticker.registerTask( Frequency.HIGH , "Events processor" , this.task ); + } + + + /** + * Clear the task reference + * + *
+ * Remove the reference to the {@link EventProcessorTask} instance, allowing the ticker to clean + * up. + */ + @Override + public void destroy( ) + { + this.task = null; + } +} diff --git a/legacyworlds-server-beans-events/src/main/java/com/deepclone/lw/beans/events/EventProcessorTask.java b/legacyworlds-server-beans-events/src/main/java/com/deepclone/lw/beans/events/EventProcessorTask.java new file mode 100644 index 0000000..4818331 --- /dev/null +++ b/legacyworlds-server-beans-events/src/main/java/com/deepclone/lw/beans/events/EventProcessorTask.java @@ -0,0 +1,86 @@ +package com.deepclone.lw.beans.events; + + +import javax.sql.DataSource; + +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; +import org.springframework.transaction.support.TransactionTemplate; + +import com.deepclone.lw.utils.StoredProc; + + + +/** + * Event processing task + * + *
+ * This class implements the task responsible for regular database event processing calls. It is
+ * registered as a high-frequency ticker task by {@link EventProcessorBean}.
+ *
+ * @author E. Benoît
+ */
+class EventProcessorTask
+ implements Runnable
+{
+
+ /** The Spring transaction template */
+ private final TransactionTemplate tTemplate;
+
+ /** The stored procedure that implements event processing */
+ private final StoredProc eqProcess;
+
+
+ /**
+ * Initialise the transaction template and stored procedure interface
+ *
+ * @param tTemplate
+ * the transaction template
+ * @param dataSource
+ * the database interface
+ */
+ public EventProcessorTask( TransactionTemplate tTemplate , DataSource dataSource )
+ {
+ this.tTemplate = tTemplate;
+ this.eqProcess = new StoredProc( dataSource , "events" , "eq_process" );
+ this.eqProcess.addOutput( "_result" , java.sql.Types.BOOLEAN );
+ }
+
+
+ /**
+ * When the task executes, it will call events.eq_process()
repeatedly until the
+ * stored procedure returns false
. Each call is made in a separate transaction.
+ */
+ @Override
+ public void run( )
+ {
+ boolean hasMore;
+ do {
+ hasMore = this.processBatch( );
+ } while ( hasMore );
+ }
+
+
+ /**
+ * Process a batch of events
+ *
+ *
+ * This method spawns a transaction in which the events.eq_process()
stored
+ * procedure is called.
+ *
+ * @return true
if events were processed, false
if the queues were
+ * empty.
+ */
+ private boolean processBatch( )
+ {
+ return this.tTemplate.execute( new TransactionCallback< Boolean >( ) {
+
+ @Override
+ public Boolean doInTransaction( TransactionStatus status )
+ {
+ return (Boolean) EventProcessorTask.this.eqProcess.execute( ).get( "_result" );
+ }
+
+ } );
+ }
+}
diff --git a/legacyworlds-server-beans-events/src/main/resources/configuration/game/events.xml b/legacyworlds-server-beans-events/src/main/resources/configuration/game/events.xml
new file mode 100644
index 0000000..bf70490
--- /dev/null
+++ b/legacyworlds-server-beans-events/src/main/resources/configuration/game/events.xml
@@ -0,0 +1,9 @@
+
+