YAACC - UPNP Client and Server
Loading...
Searching...
No Matches
de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator > Class Template Referenceabstract

Service manager of the media renderer's services that report their state in a LastChange (AVTransport and RenderingControl). More...

Inheritance diagram for de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >:
Inheritance graph
Collaboration diagram for de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >:
Collaboration graph

Public Member Functions

void fireLastChange ()
 Sends everything that changed since the last event to the subscribers, without the manager lock (see the class description).
 
- Public Member Functions inherited from org.fourthline.cling.support.lastchange.LastChangeAwareServiceManager< T extends LastChangeDelegator >
 LastChangeAwareServiceManager (LocalService< T > localService, LastChangeParser lastChangeParser)
 
 LastChangeAwareServiceManager (LocalService< T > localService, Class< T > serviceClass, LastChangeParser lastChangeParser)
 
- Public Member Functions inherited from org.fourthline.cling.model.DefaultServiceManager< T >
 DefaultServiceManager (LocalService< T > service, Class< T > serviceClass)
 
LocalService< T > getService ()
 
T getImplementation ()
 
PropertyChangeSupport getPropertyChangeSupport ()
 Provides the capability to monitor the service for state changes.
 
void execute (Command< T > cmd) throws Exception
 Double-dispatch of arbitrary commands, used by action executors and state variable accessors.
 
Collection< StateVariableValue > getCurrentState () throws Exception
 Reading the state of a service manually.
 
String toString ()
 
- Public Member Functions inherited from org.fourthline.cling.model.ServiceManager< T >

Static Public Attributes

static final long MIN_EVENT_INTERVAL_MILLIS = 250
 Minimum time between two events (the LastChange is cleared by each one, a lost event is lost for good).
 
- Static Public Attributes inherited from org.fourthline.cling.model.ServiceManager< T >
static final String EVENTED_STATE_VARIABLES = "_EventedStateVariables"
 Use this property name when propagating change events that affect any evented UPnP state variable.
 

Protected Member Functions

 AsyncLastChangeServiceManager (LocalService< T > service, LastChangeParser parser, int lockTimeoutMillis, ScheduledExecutorService executor, String logPrefix)
 
int getLockTimeoutMillis ()
 
final void attachEvents (LastChange lastChange, PropertyChangeSupport support, Object service)
 To be called by createServiceInstance() with the one instance of this manager: its LastChange and the PropertyChangeSupport the subscriptions listen at.
 
List< String > describeChanges (LastChange lastChange)
 What a log line says about the changes that are about to be sent, e.g.
 
String describeCurrentState () throws Exception
 What the log says about the state a new subscriber gets, e.g.
 
boolean isUrgent (LastChange lastChange)
 Whether the changes collected in the LastChange must be sent at once, without waiting for the pace (MIN_EVENT_INTERVAL_MILLIS).
 
Collection< StateVariableValue > readInitialEventedStateVariableValues () throws Exception
 
- Protected Member Functions inherited from org.fourthline.cling.support.lastchange.LastChangeAwareServiceManager< T extends LastChangeDelegator >
LastChangeParser getLastChangeParser ()
 
- Protected Member Functions inherited from org.fourthline.cling.model.DefaultServiceManager< T >
 DefaultServiceManager (LocalService< T > service)
 
void lock ()
 
void unlock ()
 
Collection< StateVariableValue > getCurrentState (String[] variableNames) throws Exception
 
void init ()
 
T createServiceInstance () throws Exception
 
PropertyChangeSupport createPropertyChangeSupport (T serviceImpl) throws Exception
 
PropertyChangeListener createPropertyChangeListener (T serviceImpl) throws Exception
 

Static Protected Member Functions

static ScheduledExecutorService createExecutor (String threadName)
 One idle thread at most, and not even that when nothing is evented (the thread ends after 10 s).
 

Additional Inherited Members

- Protected Attributes inherited from org.fourthline.cling.support.lastchange.LastChangeAwareServiceManager< T extends LastChangeDelegator >
final LastChangeParser lastChangeParser
 
- Protected Attributes inherited from org.fourthline.cling.model.DefaultServiceManager< T >
final LocalService< T > service
 
final Class< T > serviceClass
 
final ReentrantLock lock = new ReentrantLock(true)
 
T serviceImpl
 
PropertyChangeSupport propertyChangeSupport
 

Detailed Description

Service manager of the media renderer's services that report their state in a LastChange (AVTransport and RenderingControl).

Compared to Cling's plain DefaultServiceManager it

  • sends the full state of the service (all variables of the instance, not only what changed since the start) to a new subscriber, as UPnP requires for the initial event, and
  • sends the LastChange to the subscribers after every change. Without that nothing was ever sent after the initial event: a control point such as Home Assistant, which relies on events for CurrentPlayMode, Mute and Volume once it is subscribed, never saw a change.

Events never hold up a command. Actions run under this manager's lock (Cling's AbstractActionExecutor), and a command that cannot get the lock within the timeout fails with a UPnP error: the control point logs it and the command is lost. Cling's fireLastChange() takes that lock and delivers to the subscriptions while holding it, so one slow or blocked subscriber (a subscription's methods are synchronized and some of them need the manager lock themselves) stopped every command. Here the events are sent from a background thread that takes no manager lock: it takes what changed out of the LastChange in one step (the monitor of the LastChange, held for microseconds, is all it shares with a command) and then hands it to each subscriber on its own, a failing subscriber being logged and skipped. Several changes in a row are sent together; two events are at least MIN_EVENT_INTERVAL_MILLIS apart (from the end of one to the start of the next), so nothing is sent at a pace a control point could not follow. Except a change of the state of the service (isUrgent: the transport state): it goes out at once, with whatever else is pending. A control point decides what to send next from the last state it was told (Home Assistant skips its Play when the last TransportState it saw says PLAYING), and one that acts right after its own command - Stop, SetAVTransportURI, look at the state - must not find the state it just changed delayed.

A subclass creates the service instance, calls attachEvents with it, and says what it wants to see in the log (describeChanges, describeCurrentState).

Constructor & Destructor Documentation

◆ AsyncLastChangeServiceManager()

de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >.AsyncLastChangeServiceManager ( LocalService< T > service,
LastChangeParser parser,
int lockTimeoutMillis,
ScheduledExecutorService executor,
String logPrefix )
protected
Parameters
logPrefixshort name of the service in the log lines (AVT, RCS)

Member Function Documentation

◆ attachEvents()

final void de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >.attachEvents ( LastChange lastChange,
PropertyChangeSupport support,
Object service )
protected

To be called by createServiceInstance() with the one instance of this manager: its LastChange and the PropertyChangeSupport the subscriptions listen at.

From then on every change of an ObservableLastChange asks for an event.

◆ describeChanges()

List< String > de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >.describeChanges ( LastChange lastChange)
protected

What a log line says about the changes that are about to be sent, e.g.

CurrentPlayMode=NORMAL
(instance 0)
; one text per line. Called while the LastChange is locked: only read it.

Reimplemented in de.yaacc.upnp.server.avtransport.AvTransportServiceManager, and de.yaacc.upnp.server.renderingcontrol.RenderingControlServiceManager.

Referenced by de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >.fireLastChange().

Here is the caller graph for this function:

◆ describeCurrentState()

String de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >.describeCurrentState ( ) throws Exception
protected

What the log says about the state a new subscriber gets, e.g.

CurrentPlayMode=NORMAL; null for nothing. Called under the manager lock after the state was read.

Reimplemented in de.yaacc.upnp.server.avtransport.AvTransportServiceManager, and de.yaacc.upnp.server.renderingcontrol.RenderingControlServiceManager.

◆ fireLastChange()

Sends everything that changed since the last event to the subscribers, without the manager lock (see the class description).

Does nothing when nothing changed.

Reimplemented from org.fourthline.cling.support.lastchange.LastChangeAwareServiceManager< T extends LastChangeDelegator >.

Here is the call graph for this function:

◆ getLockTimeoutMillis()

◆ isUrgent()

boolean de.yaacc.upnp.server.events.AsyncLastChangeServiceManager< T extends LastChangeDelegator >.isUrgent ( LastChange lastChange)
protected

Whether the changes collected in the LastChange must be sent at once, without waiting for the pace (MIN_EVENT_INTERVAL_MILLIS).

The default is no: volume and mute may wait. Called with the LastChange locked: only read it, and quickly.

Reimplemented in de.yaacc.upnp.server.avtransport.AvTransportServiceManager.

◆ readInitialEventedStateVariableValues()


The documentation for this class was generated from the following file: