Esempio n. 1
0
func main() {
	go func() {
		for {
			time.Sleep(time.Duration(1) * time.Second)
			ob.Publish("foo", time.Now().Unix())
		}
	}()

	eventCh1 := make(chan interface{})
	ob.Subscribe("foo", eventCh1)
	go func() {
		for {
			data := <-eventCh1
			fmt.Printf("sub1: %#v\n", data)
		}
	}()

	eventCh2 := make(chan interface{})
	ob.Subscribe("foo", eventCh2)
	go func() {
		for {
			data := <-eventCh2
			fmt.Printf("sub2: %v\n", data)
		}
	}()

	<-time.After(6 * time.Second)

	// Output:
}
Esempio n. 2
0
func (config *Config) Merge(branch Config) {

	// merge networks
	if len(branch.Networks) > 0 {
		oldConfig := *config
		config.Networks = branch.Networks

		// detect changes
		oldInterfaces := oldConfig.GetInterfaces()
		newInterfaces := config.GetInterfaces()

		deletedInterfaces := oldInterfaces.Difference(newInterfaces)

		for interfaceName := range deletedInterfaces.Iter() {

			observer.Publish(EVENT_DELETE_INTERFACE, interfaceName)

		}
	}

	Trace.Print("merged: %v", config)
}
Esempio n. 3
0
func (e *EngineConfig) ServeForever() {
	var (
		outputsWg = new(sync.WaitGroup)
		filtersWg = new(sync.WaitGroup)
		inputsWg  = new(sync.WaitGroup)
		globals   = Globals()
		err       error
	)

	// setup signal handler first to avoid race condition
	// if Input terminates very soon, global.Shutdown will
	// not be able to trap it
	globals.sigChan = make(chan os.Signal)
	signal.Notify(globals.sigChan, syscall.SIGINT, syscall.SIGHUP,
		syscall.SIGUSR2, syscall.SIGUSR1)

	e.launchHttpServ()

	if globals.Verbose {
		globals.Println("Launching Output(s)...")
	}
	for _, runner := range e.OutputRunners {
		outputsWg.Add(1)
		if err = runner.start(e, outputsWg); err != nil {
			panic(err)
		}
	}

	if globals.Verbose {
		globals.Println("Launching Filter(s)...")
	}
	for _, runner := range e.FilterRunners {
		filtersWg.Add(1)
		if err = runner.start(e, filtersWg); err != nil {
			panic(err)
		}
	}

	// setup the diagnostic trackers
	inputPackTracker := NewDiagnosticTracker("inputPackTracker")
	e.diagnosticTrackers[inputPackTracker.PoolName] = inputPackTracker
	filterPackTracker := NewDiagnosticTracker("filterPackTracker")
	e.diagnosticTrackers[filterPackTracker.PoolName] = filterPackTracker

	if globals.Verbose {
		globals.Printf("Initializing PipelinePack pools with size=%d\n",
			globals.RecyclePoolSize)
	}
	for i := 0; i < globals.RecyclePoolSize; i++ {
		inputPack := NewPipelinePack(e.inputRecycleChan)
		inputPackTracker.AddPack(inputPack)
		e.inputRecycleChan <- inputPack

		filterPack := NewPipelinePack(e.filterRecycleChan)
		filterPackTracker.AddPack(filterPack)
		e.filterRecycleChan <- filterPack
	}

	go inputPackTracker.Run(e.Int("diagnostic_interval", 20))
	go filterPackTracker.Run(e.Int("diagnostic_interval", 20))

	// check if we have enough recycle pool reservation
	go func() {
		t := time.NewTicker(time.Second * time.Duration(globals.TickerLength))
		defer t.Stop()

		var inputPoolSize, filterPoolSize int

		for _ = range t.C {
			inputPoolSize = len(e.inputRecycleChan)
			filterPoolSize = len(e.filterRecycleChan)
			if globals.Verbose || inputPoolSize == 0 || filterPoolSize == 0 {
				globals.Printf("Recycle poolSize: [input]%d [filter]%d",
					inputPoolSize, filterPoolSize)
			}
		}
	}()

	go e.router.Start()

	for _, project := range e.projects {
		project.Start()
	}

	if globals.Verbose {
		globals.Println("Launching Input(s)...")
	}
	for _, runner := range e.InputRunners {
		inputsWg.Add(1)
		if err = runner.start(e, inputsWg); err != nil {
			inputsWg.Done()
			panic(err)
		}
	}

	globals.Println("Engine mainloop, waiting for signals...")
	go runShutdownWatchdog(e)

	for !globals.Stopping {
		select {
		case sig := <-globals.sigChan:
			globals.Printf("Got signal %s\n", sig.String())
			switch sig {
			case syscall.SIGHUP:
				globals.Println("Reloading...")
				observer.Publish(RELOAD, nil)

			case syscall.SIGINT:
				globals.Println("Engine shutdown...")
				globals.Stopping = true

			case syscall.SIGUSR1:
				observer.Publish(SIGUSR1, nil)

			case syscall.SIGUSR2:
				observer.Publish(SIGUSR2, nil)
			}
		}
	}

	// cleanup after shutdown
	inputPackTracker.Stop()
	filterPackTracker.Stop()

	e.Lock()
	for _, runner := range e.InputRunners {
		if runner == nil {
			// this Input plugin already exit
			continue
		}

		if globals.Verbose {
			globals.Printf("Stop message sent to '%s'", runner.Name())
		}

		runner.Input().Stop()
	}
	e.Unlock()
	inputsWg.Wait() // wait for all inputs done
	if globals.Verbose {
		globals.Println("All Inputs terminated")
	}

	// ok, now we are sure no more inputs, but in route.inChan there
	// still may be filter injected packs and output not consumed packs
	// we must wait for all the packs to be consumed before shutdown

	for _, runner := range e.FilterRunners {
		if globals.Verbose {
			globals.Printf("Stop message sent to '%s'", runner.Name())
		}

		e.router.removeFilterMatcher <- runner.Matcher()
	}
	filtersWg.Wait()
	if globals.Verbose {
		globals.Println("All Filters terminated")
	}

	for _, runner := range e.OutputRunners {
		if globals.Verbose {
			globals.Printf("Stop message sent to '%s'", runner.Name())
		}

		e.router.removeOutputMatcher <- runner.Matcher()
	}
	outputsWg.Wait()
	if globals.Verbose {
		globals.Println("All Outputs terminated")
	}

	//close(e.router.inChan)

	e.stopHttpServ()

	for _, project := range e.projects {
		project.Stop()
	}

	globals.Printf("Shutdown with input:%s, dispatched:%s",
		gofmt.Comma(e.router.stats.TotalInputMsgN),
		gofmt.Comma(e.router.stats.TotalProcessedMsgN))
}