2014-04-26 09:18:56 +00:00
package ICCC
2014-10-19 17:19:11 +00:00
import (
"github.com/SommerEngineering/Ocean/ICCC/Scheme"
"github.com/SommerEngineering/Ocean/Log"
LM "github.com/SommerEngineering/Ocean/Log/Meta"
)
2014-04-26 09:18:56 +00:00
2015-06-17 15:44:52 +00:00
// Function to broadcast a message to all listeners.
2015-07-13 08:44:03 +00:00
func WriteMessage2All ( channel , command string , kind byte , message interface { } , answerPrototype interface { } ) ( results [ ] interface { } ) {
2014-04-26 09:18:56 +00:00
cacheListenerDatabaseLock . RLock ( )
defer cacheListenerDatabaseLock . RUnlock ( )
2015-06-17 15:44:52 +00:00
// Convert the message to HTTP data:
2015-06-21 18:18:23 +00:00
data := Message2Data ( channel , command , message )
// Store all matching listener:
matchingListener := make ( [ ] Scheme . Listener , 0 )
2015-06-17 15:44:52 +00:00
// Loop over all listeners which are currently available at the cache:
2014-04-26 09:18:56 +00:00
for entry := cacheListenerDatabase . Front ( ) ; entry != nil ; entry = entry . Next ( ) {
listener := entry . Value . ( Scheme . Listener )
2015-06-17 15:44:52 +00:00
2015-07-13 08:44:03 +00:00
// If the channel, command and kind matches, deliver the message:
if kind == KindALL {
if listener . Channel == channel && listener . Command == command {
matchingListener = append ( matchingListener , listener )
}
} else {
if listener . Channel == channel && listener . Command == command && listener . Kind == kind {
matchingListener = append ( matchingListener , listener )
}
2014-04-26 09:18:56 +00:00
}
}
2015-06-21 18:18:23 +00:00
// Was not able to find any matching listener?
if len ( matchingListener ) == 0 {
2014-04-26 09:18:56 +00: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 18:18:23 +00: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 09:18:56 +00:00
}
return
}