2014-04-26 11:18:56 +02:00
package ICCC
2014-10-19 19:19:11 +02:00
import (
"github.com/SommerEngineering/Ocean/ICCC/Scheme"
"github.com/SommerEngineering/Ocean/Log"
LM "github.com/SommerEngineering/Ocean/Log/Meta"
)
2014-04-26 11:18:56 +02:00
2015-06-17 17:44:52 +02:00
// Function to broadcast a message to all listeners.
2015-06-21 20:18:23 +02:00
func WriteMessage2All ( channel , command string , message interface {}, answerPrototype interface {}) ( results [] interface {}) {
2014-04-26 11:18:56 +02:00
cacheListenerDatabaseLock . RLock ()
defer cacheListenerDatabaseLock . RUnlock ()
2015-06-17 17:44:52 +02:00
// Convert the message to HTTP data:
2015-06-21 20:18:23 +02:00
data := Message2Data ( channel , command , message )
// Store all matching listener:
matchingListener := make ([] Scheme . Listener , 0 )
2015-06-17 17:44:52 +02:00
// Loop over all listeners which are currently available at the cache:
2014-04-26 11:18:56 +02:00
for entry := cacheListenerDatabase . Front (); entry != nil ; entry = entry . Next () {
listener := entry . Value .( Scheme . Listener )
2015-06-17 17:44:52 +02:00
// If the channel and the command matches, deliver the message:
2014-04-26 11:18:56 +02:00
if listener . Channel == channel && listener . Command == command {
2015-06-21 20:18:23 +02:00
matchingListener = append ( matchingListener , listener )
2014-04-26 11:18:56 +02:00
}
}
2015-06-21 20:18:23 +02:00
// Was not able to find any matching listener?
if len ( matchingListener ) == 0 {
2014-04-26 11:18:56 +02:00
Log . LogFull ( senderName , LM . CategorySYSTEM , LM . LevelWARN , LM . SeverityCritical , LM . ImpactUnknown , LM . MessageNameCONFIGURATION , `It was not able to deliver this message, because no listener was found!` , `channel=` + channel , `command=` + command )
2015-06-21 20:18:23 +02:00
return
}
// Create an channel to receive all the answers from all listeners:
answerChannel := make ( chan map [ string ][] string , len ( matchingListener ))
// Start for every listener an own thread:
for _ , listener := range matchingListener {
go func () {
answerChannel <- sendMessage ( listener , data )
}()
}
// Reserve memory for the result data:
results = make ([] interface {}, len ( matchingListener ))
// Read all answers:
for n := 0 ; n < len ( matchingListener ); n ++ {
//
// We use no timeout here. This way, it is also possible to execute
// long running commands by ICCC. The caller can abort, if necessary.
//
answersData := <- answerChannel
// Convert the data to the message type. The call will use answerPrototype
// just as a prototype and will create a new instance for every call:
_ , _ , results [ n ] = Data2Message ( answerPrototype , answersData )
2014-04-26 11:18:56 +02:00
}
return
}