Threading in your custom module

A very common problem that you as a Wowza module developer might face is performing some action periodically in your custom module. The IModuleBase class does not offer you a way to register any periodic callback in your VHost. In this article I would like to show a simple way to achieve this.

Extending VHostWorkerThread

There is a base class called VHostWorkerThread that allows you to create your threads in the context of the virtual host. By inspectint the obfuscated codebase of the parent class, the main benefit of doing this instead of simply extending Thread is basically the better logging. Whenever you do logging from your thread via the WMSLoggerInstance, the right contextual details will be added to your log entry, such as the server's name.

package com.wowzatoolbox;

import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.module.ModuleBase;

public class PeriodicDemo extends ModuleBase {

 private MyPeriodicStuff monitor;

 public void onAppStart(IApplicationInstance appInstance) {
  monitor = new MyPeriodicStuff(appInstance);
  monitor.start();
 }

}

The actual periodic job can be implemented like this

package com.wowzatoolbox;

import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.logging.WMSLogger;
import com.wowza.wms.logging.WMSLoggerFactory;
import com.wowza.wms.vhost.VHostWorkerThread;

public class MyPeriodicStuff extends VHostWorkerThread {

 private IApplicationInstance appInstance;

 private WMSLogger logger;

 private long lastRun;

 private long monitorIntervalMillis;

 public MyPeriodicStuff(IApplicationInstance appInstance) {
  super(appInstance.getVHost());
  this.appInstance = appInstance;
  this.monitorIntervalMillis = 5 * 1000;
  logger = WMSLoggerFactory.getLoggerObj(appInstance);
  setDaemon(true);
 }

 @Override
 public void run() {
  logger.info("My periodic stuff kicked off with period time: " + monitorIntervalMillis / 1000);

  while(true) {

   long currTime = System.currentTimeMillis();

   if (currTime > monitorIntervalMillis + lastRun) {
    logger.info("Doing something useful again");
    lastRun = currTime;
   }

   try {
    sleep(100);
   } catch (InterruptedException ignored) {
   }

  }
 }

}

This is a very simple approach is not the most CPU effective implementation, but may give you the idea of doing something periodical in your own Wowza module.