diff --git a/config/config.go b/config/config.go index ff06e7c..26b68ac 100644 --- a/config/config.go +++ b/config/config.go @@ -126,7 +126,7 @@ var ( databasePath = flag.String("dbpath", "/tmp/testdb", "Path to the database.") databaseBackend = flag.String("db", "memstore", "Database Backend.") replicationBackend = flag.String("replication", "single", "Replication method.") - host = flag.String("host", "0.0.0.0", "Host to listen on (defaults to all).") + host = flag.String("host", "127.0.0.1", "Host to listen on (defaults to all).") loadSize = flag.Int("load_size", 10000, "Size of triplesets to load") port = flag.String("port", "64210", "Port to listen on.") readOnly = flag.Bool("read_only", false, "Disable writing via HTTP.") diff --git a/docs/Configuration.md b/docs/Configuration.md index b464adb..4b6b898 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -39,7 +39,7 @@ All command line flags take precedence over the configuration file. #### **`listen_host`** * Type: String - * Default: "0.0.0.0" + * Default: "127.0.0.1" The hostname or IP address for Cayley's HTTP server to listen on. Defaults to all interfaces. diff --git a/docs/Overview.md b/docs/Overview.md index cea43c6..300d005 100644 --- a/docs/Overview.md +++ b/docs/Overview.md @@ -62,7 +62,7 @@ Just as before: And you'll see a message not unlike ```bash -Cayley now listening on 0.0.0.0:64210 +Cayley now listening on 127.0.0.1:64210 ``` If you visit that address (often, [http://localhost:64210](http://localhost:64210)) you'll see the full web interface and also have a graph ready to serve queries via the [HTTP API](/docs/HTTP.md) diff --git a/query/gremlin/finals.go b/query/gremlin/finals.go index a82da13..6979e22 100644 --- a/query/gremlin/finals.go +++ b/query/gremlin/finals.go @@ -210,6 +210,7 @@ func runIteratorToArrayNoTags(it graph.Iterator, ses *Session, limit int) []stri func runIteratorWithCallback(it graph.Iterator, ses *Session, callback otto.Value, this otto.FunctionCall, limit int) { count := 0 it, _ = it.Optimize() + glog.V(2).Infoln(it.DebugString(0)) for { select { case <-ses.kill: diff --git a/query/gremlin/session.go b/query/gremlin/session.go index 8000c17..d1c84b5 100644 --- a/query/gremlin/session.go +++ b/query/gremlin/session.go @@ -22,6 +22,7 @@ import ( "time" "github.com/robertkrimen/otto" + _ "github.com/robertkrimen/otto/underscore" "github.com/google/cayley/graph" "github.com/google/cayley/query" @@ -93,8 +94,11 @@ func (s *Session) SendResult(r *Result) bool { if s.limit >= 0 && s.limit == s.count { return false } + s.envLock.Lock() + kill := s.kill + s.envLock.Unlock() select { - case <-s.kill: + case <-kill: return false default: } @@ -111,7 +115,6 @@ func (s *Session) SendResult(r *Result) bool { } func (s *Session) runUnsafe(input interface{}) (otto.Value, error) { - s.kill = make(chan struct{}) defer func() { if r := recover(); r != nil { if r == ErrKillTimeout { @@ -125,25 +128,41 @@ func (s *Session) runUnsafe(input interface{}) (otto.Value, error) { // Use buffered chan to prevent blocking. s.env.Interrupt = make(chan func(), 1) + ready := make(chan struct{}) + done := make(chan struct{}) if s.timeout >= 0 { go func() { time.Sleep(s.timeout) - close(s.kill) - s.envLock.Lock() - defer s.envLock.Unlock() - if s.env != nil { - s.env.Interrupt <- func() { - panic(ErrKillTimeout) + <-ready + select { + case <-done: + return + default: + close(s.kill) + s.envLock.Lock() + defer s.envLock.Unlock() + s.kill = nil + if s.env != nil { + s.env.Interrupt <- func() { + panic(ErrKillTimeout) + } + s.env = s.emptyEnv } - s.env = s.emptyEnv + return } }() } s.envLock.Lock() env := s.env + if s.kill == nil { + s.kill = make(chan struct{}) + } s.envLock.Unlock() - return env.Run(input) + close(ready) + out, err := env.Run(input) + close(done) + return out, err } func (s *Session) ExecInput(input string, out chan interface{}, limit int) { @@ -254,8 +273,11 @@ func (s *Session) GetJson() ([]interface{}, error) { if s.err != nil { return nil, s.err } + s.envLock.Lock() + kill := s.kill + s.envLock.Unlock() select { - case <-s.kill: + case <-kill: return nil, ErrKillTimeout default: return s.dataOutput, nil