func forEachList(vm *VM, obj []interface{}, workerNum int, f func(item interface{}) error) error { if obj == nil { return nil } size := len(obj) if size == 0 { return nil } if workerNum == 0 { for _, value := range obj { select { case f := <-vm.StopChan: f() return nil default: err := f(value) if err != nil { return err } } } return nil } queue := job.NewQueue(uint(workerNum)) for _, item := range obj { localItem := item queue.Add(job.NewJob(func() { f(localItem) })) } queue.Wait() return nil }
//Sync Watch Process func startSyncWatchProcess(server *Server) { config := util.GetConfig() watch := config.GetStringList("watch/keys", nil) events := config.GetStringList("watch/events", nil) if watch == nil { return } extensions := map[string]extension.Environment{} for _, event := range events { path := "sync://" + event env, err := server.NewEnvironmentForPath("sync."+event, path) if err != nil { log.Fatal(err.Error()) } extensions[event] = env } responseChan := make(chan *gohan_sync.Event) stopChan := make(chan bool) for _, path := range watch { go func(path string) { defer util.LogFatalPanic(log) for server.running { lockKey := lockPath + "watch" err := server.sync.Lock(lockKey, true) if err != nil { log.Warning("Can't start watch process due to lock", err) time.Sleep(5 * time.Second) continue } defer func() { server.sync.Unlock(lockKey) }() err = server.sync.Watch(path, responseChan, stopChan) if err != nil { log.Error(fmt.Sprintf("sync watch error: %s", err)) } } }(path) } //main response lisnter process go func() { defer util.LogFatalPanic(log) for server.running { response := <-responseChan server.queue.Add(job.NewJob( func() { defer util.LogPanic(log) for _, event := range events { //match extensions if strings.HasPrefix(response.Key, "/"+event) { env := extensions[event] runExtensionOnSync(server, response, env.Clone()) return } } })) } }() }
func backgroundJob(stmt *gohanscript.Stmt) (func(*gohanscript.Context) (interface{}, error), error) { stmts, err := gohanscript.MakeStmts(stmt.File, stmt.RawNode["job"]) if err != nil { return nil, stmt.Errorf("background code error: %s", err) } queueArg, err := gohanscript.NewValue(stmt.RawData["queue"]) if err != nil { return nil, stmt.Errorf("background code error: %s", err) } f, err := gohanscript.StmtsToFunc("job", stmts) if err != nil { return nil, err } return func(context *gohanscript.Context) (interface{}, error) { queue := queueArg.Value(context).(*job.Queue) newContext := context.Extend(map[string]interface{}{}) queue.Add( job.NewJob(func() { f(newContext) newContext.VM.Stop() })) return nil, nil }, nil }