package runtime import ( "fmt" "sync" "github.com/safing/portbase/database" "github.com/safing/portbase/database/record" "github.com/safing/portbase/log" "github.com/safing/portbase/modules" ) var modulesIntegrationUpdatePusher func(...record.Record) func startModulesIntegration() (err error) { modulesIntegrationUpdatePusher, err = Register("modules/", &ModulesIntegration{}) if err != nil { return err } if !modules.SetEventSubscriptionFunc(pushModuleEvent) { log.Warningf("runtime: failed to register the modules event subscription function") } return nil } // ModulesIntegration provides integration with the modules system. type ModulesIntegration struct{} // Set is called when the value is set from outside. // If the runtime value is considered read-only ErrReadOnly // should be returned. It is guaranteed that the key of // the record passed to Set is prefixed with the key used // to register the value provider. func (mi *ModulesIntegration) Set(record.Record) (record.Record, error) { return nil, ErrReadOnly } // Get should return one or more records that match keyOrPrefix. // keyOrPrefix is guaranteed to be at least the prefix used to // register the ValueProvider. func (mi *ModulesIntegration) Get(keyOrPrefix string) ([]record.Record, error) { return nil, database.ErrNotFound } type eventData struct { record.Base sync.Mutex Data interface{} } func pushModuleEvent(moduleName, eventName string, internal bool, data interface{}) { // Create event record and set key. eventRecord := &eventData{ Data: data, } eventRecord.SetKey(fmt.Sprintf( "runtime:modules/%s/event/%s", moduleName, eventName, )) eventRecord.UpdateMeta() if internal { eventRecord.Meta().MakeSecret() eventRecord.Meta().MakeCrownJewel() } // Push event to database subscriptions. modulesIntegrationUpdatePusher(eventRecord) }