func (this *SandboxManagerFilter) Run(fr pipeline.FilterRunner, h pipeline.PluginHelper) (err error) { inChan := fr.InChan() var ok = true var pack *pipeline.PipelinePack var delta int64 this.restoreSandboxes(fr, h, this.workingDirectory) for ok { select { case pack, ok = <-inChan: if !ok { break } atomic.AddInt64(&this.processMessageCount, 1) delta = time.Now().UnixNano() - pack.Message.GetTimestamp() if math.Abs(float64(delta)) >= 5e9 { fr.UpdateCursor(pack.QueueCursor) pack.Recycle(fmt.Errorf("Discarded control message: %d seconds skew", delta/1e9)) break } action, _ := pack.Message.GetFieldValue("action") switch action { case "load": current := int(atomic.LoadInt32(&this.currentFilters)) if current < this.maxFilters { err := this.loadSandbox(fr, h, this.workingDirectory, pack.Message) if err != nil { p, e := h.PipelinePack(0) if e != nil { fr.LogError(err) fr.LogError(fmt.Errorf("can't send termination message: %s", e.Error())) break } p.Message.SetType("heka.sandbox-terminated") p.Message.SetLogger(pipeline.HEKA_DAEMON) message.NewStringField(p.Message, "plugin", fr.Name()) p.Message.SetPayload(err.Error()) fr.Inject(p) fr.LogError(err) } } else { fr.LogError(fmt.Errorf("%s attempted to load more than %d filters", fr.Name(), this.maxFilters)) } case "unload": fv, _ := pack.Message.GetFieldValue("name") if name, ok := fv.(string); ok { name = getSandboxName(fr.Name(), name) if this.pConfig.RemoveFilterRunner(name) { removeAll(this.workingDirectory, fmt.Sprintf("%s.*", name)) } } } pack.Recycle(nil) } } return }