package com.destinationradiodenver.mobileStreaming.singleton; import java.io.Serializable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.ejb.AccessTimeout; import javax.ejb.ConcurrencyManagement; import javax.ejb.ConcurrencyManagementType; import javax.ejb.EJB; import javax.ejb.Lock; import javax.ejb.LockType; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.inject.Inject; import org.jboss.logging.Logger; import org.red5.service.httpstream.model.MobileProfile; import com.destinationradiodenver.mobileStreaming.EncoderStatusDispatcher; import com.destinationradiodenver.mobileStreaming.FfThread; import com.destinationradiodenver.mobileStreaming.messages.EncoderStatusMessage; @Startup @Singleton @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) @AccessTimeout(value=10, unit=TimeUnit.SECONDS) @Lock(LockType.READ) public class FfThreads extends ConcurrentHashMap<String, FfThread> implements Serializable { /** * @author cpenhale */ private static final long serialVersionUID = -7647887359926613782L; private Logger log = Logger.getLogger(FfThreads.class); @Inject private AvailabilityService availabilityService; @EJB private SegmentConsumers segmentConsumers; private static EncoderStatusDispatcher encoderStatusDispatcher = new EncoderStatusDispatcher(); public FfThreads(){ log.info("Creating Ffthreads Singleton"); } @PostConstruct private void init(){ log.info("Encoders Ffthreads initialized"); } @Lock(LockType.WRITE) public void startFfThread(FfThread ffThread){ String name = ffThread.getStreamName()+"_"+ffThread.getMobileProfile().getName(); log.infof("Attempting to start a new FfThread %s", name); if(super.containsKey(name)){ log.warnf("Someone is attempting to add FfThread %s to FfThreads. Stopping existing FfThread before starting a new one", name); stopFfThread(name, ffThread.getSourceURI(), ffThread.getMobileProfile()); } segmentConsumers.startSegmentConsumerForFfThread(ffThread); new Thread(ffThread).start(); super.put(ffThread.getStreamName()+"_"+ffThread.getMobileProfile().getName(), ffThread); } @Lock(LockType.WRITE) public void stopFfThread(String name, String fullUri, MobileProfile mobileProfile){ log.infof("Stopping FfThread %s", name); FfThread ffThread = super.get(name); if(ffThread!=null){ ffThread.setInterruptMe(true); segmentConsumers.stopSegmentConsumer(name); super.remove(name); }else{ log.error("Attempted to stop FfThread that doesn't exist in FfThreads. Sending 'stopped' message"); EncoderStatusMessage statusMessage = new EncoderStatusMessage(); statusMessage.setUri(fullUri); statusMessage.setHeight(mobileProfile.getHeight()); statusMessage.setWidth(mobileProfile.getWidth()); statusMessage.setBandwidth(mobileProfile.getBandwidth()); statusMessage.setName(mobileProfile.getName()); encoderStatusDispatcher.dispatch(statusMessage); } } }