func main() { es, err := bandit.NewExperiments(bandit.NewOpener(*apiExperiments)) if err != nil { log.Fatalf("could not initialize experiments: %s", err.Error()) } m := pat.New() m.Get("/experiments/:name", http.HandlerFunc(bhttp.SelectionHandler(es, *apiPinTTL))) http.Handle("/", m) // serve log.Fatal(http.ListenAndServe(*apiBind, nil)) }
// simple produces a snapshot every `poll` duration. FIXME: O(N) memory func simple(s *statistics, logFile string, poll time.Duration) error { snapshotFile := s.experimentName + ".tsv" opener := bandit.NewOpener(logFile) file, err := opener.Open() if err != nil { return fmt.Errorf("could not open logs: %s", err.Error()) } defer file.Close() go func() { t := time.NewTicker(poll) for _ = range t.C { file, err := opener.Open() if err != nil { log.Printf("error opening log: %s", err.Error()) } // map rM, wM := file, new(bytes.Buffer) m := mapper(s, rM, wM) m() mapped := wM.String() // reduce rR, wR := strings.NewReader(mapped), new(bytes.Buffer) r := reducer(s, rR, wR) r() reduced := strings.TrimRight(wR.String(), "\n ") snapshot, err := os.Create(snapshotFile) if err != nil { log.Printf("error creating snapshot file: %s", err.Error()) } defer snapshot.Close() snapshot.Write([]byte(reduced)) } }() select {} }