func main() { pflag.Usage = func() { fmt.Printf(`usage: tuplespaced [flags] Run tuplespace server. Flags: `) pflag.PrintDefaults() } pflag.Parse() runtime.GOMAXPROCS(*ncpuFlag) log.AddFilter("stdout", logLevels[*logLevelFlag], log.NewConsoleLogWriter()) debug := logLevels[*logLevelFlag] <= log.DEBUG log.Info("Starting server on http://%s/tuplespace/", *bindFlag) ts := tuplespace.NewTupleSpace(store.NewMemoryStore()) srv := &http.Server{ Addr: *bindFlag, Handler: makeService(ts, debug), ReadTimeout: *readTimeoutFlag, WriteTimeout: *writeTimeoutFlag, } err := srv.ListenAndServe() if err != nil { fatalf("error: %s\n", err) } }
// Benchmark implementations func benchmarkTupleSpaceSend(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() b.ResetTimer() for i := 0; i < b.N; i++ { ts.Send(tuplespace.Tuple{"cmd": "uname -a"}, 0) } }
func TestTupleSpaceTake(t *testing.T) { ts := tuplespace.NewTupleSpace(store.NewMemoryStore()) defer ts.Shutdown() ts.Send(tuplespace.Tuple{"cmd": "uname -a"}, 0) ts.Send(tuplespace.Tuple{"cmd": "uptime"}, 0) _, err := ts.Take(tuplespace.MustMatch(`cmd != nil`), time.Second) assert.NoError(t, err) assert.Equal(t, ts.Stats().Tuples, 1) }
func benchmarkTupleSpaceReadAll1000(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() sendN(ts, 1000, 0) b.ResetTimer() match := tuplespace.MustMatch(`cmd != nil`) for i := 0; i < b.N; i++ { ts.ReadAll(match, 0) } }
func benchmarkTupleSpaceTake(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() sendN(ts, b.N, 0) b.ResetTimer() for i := 0; i < b.N; i++ { match := tuplespace.MustMatch(`cmd == %d`, i) ts.Take(match, 0) } }
func TestTupleSpaceReadAll(t *testing.T) { ts := tuplespace.NewTupleSpace(store.NewMemoryStore()) defer ts.Shutdown() ts.Send(tuplespace.Tuple{"cmd": "uname -a"}, 0) ts.Send(tuplespace.Tuple{"cmd": "uptime"}, 0) time.Sleep(time.Millisecond * 100) tuples, err := ts.ReadAll(tuplespace.MustMatch(`cmd != nil`), time.Second) assert.NoError(t, err) assert.Equal(t, tuples, []tuplespace.Tuple{tuplespace.Tuple{"cmd": "uname -a"}, tuplespace.Tuple{"cmd": "uptime"}}) assert.Equal(t, ts.Stats().Tuples, 2) }
func benchmarkTupleSpaceRead(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() sendN(ts, b.N, 0) sendN(ts, b.N, 0) b.ResetTimer() for i := 0; i < b.N; i++ { match := tuplespace.MustMatch(`cmd == %d`, int64(i)) _, err := ts.Read(match, 0) if err != nil { panic(err.Error()) } } }
func benchmarkTupleSpaceStressTestConcurrency32(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() threads := 32 messages := b.N var sent int32 var read int32 readWait := sync.WaitGroup{} for i := 0; i < threads; i++ { readWait.Add(1) go func(i int) { for n := 0; n < messages; n++ { match := tuplespace.MustMatch(`"a" == "reader" && "b" == %d && "c" == %d`, i, n) _, err := ts.Take(match, time.Minute) if err != nil { fmt.Errorf("failed to take: %s", err) } else { atomic.AddInt32(&read, 1) } } readWait.Done() }(i) } writeWait := sync.WaitGroup{} for i := 0; i < threads; i++ { writeWait.Add(1) go func(i int) { for n := 0; n < messages; n++ { tuple := tuplespace.Tuple{"a": "reader", "b": int64(i), "c": int64(n)} err := ts.Send(tuple, 0) if err != nil { fmt.Errorf("failed to take: %s", err) } else { atomic.AddInt32(&sent, 1) } } writeWait.Done() }(i) } writeWait.Wait() if int(sent) != threads*messages { panic("consistency check failed") } readWait.Wait() if sent != read { panic("consistency check failed") } // assert.Equal(t, ts.Stats(), tuplespace.TupleSpaceStats{ // TuplesSeen: int64(threads * messages), // WaitersSeen: int64(threads * messages), // TuplesTaken: int64(threads * messages), // TuplesRead: 0, // }) }