func (this *InterpretedExecutor) processItem(q network.Query, item *dparval.Value) bool { projection := item.GetAttachment("projection") switch projection := projection.(type) { case *dparval.Value: result := projection.Value() q.Response().SendResult(result) } return true }
func Dispatch(q network.Query, comp compiler.Compiler, exec executor.Executor, timeout *time.Duration) { request := q.Request() response := q.Response() switch request := request.(type) { case network.StringQueryRequest: plan, err := comp.Compile(request.QueryString) if err != nil { response.SendError(err) return } exec.Execute(plan, q, timeout) } }
func (this *InterpretedExecutor) executeInternal(optimalPlan *plan.Plan, q network.Query, timeoutStopChannel misc.StopChannel) { clog.To(executor.CHANNEL, "simple executor started") // first make the plan excutable executablePipeline, berr := this.xpipelinebuilder.Build(optimalPlan, q) if berr != nil { q.Response().SendError(query.NewError(berr, "")) return } root := executablePipeline.Root // create a stop channel stopChannel := make(misc.StopChannel) // set it on the query object, so HTTP layer can // stop us if the client goes away q.SetStopChannel(stopChannel) go root.Run(stopChannel) // now execute it var item *dparval.Value var obj interface{} sourceItemChannel, supportChannel := root.GetChannels() ok := true for ok { select { case item, ok = <-sourceItemChannel: if ok { ok = this.processItem(q, item) clog.To(executor.CHANNEL, "simple executor sent client item: %v", item) } case obj, ok = <-supportChannel: if ok { switch obj := obj.(type) { case query.Error: q.Response().SendError(obj) clog.To(executor.CHANNEL, "simple executor sent client error: %v", obj) if obj.IsFatal() { return } } } case _, ok = <-timeoutStopChannel: clog.To(executor.CHANNEL, "simple execution aborted, timeout") return } } q.Response().NoMoreResults() clog.To(executor.CHANNEL, "simple executor finished") }
func (this *InterpretedExecutor) Execute(optimalPlan *plan.Plan, q network.Query, timeout *time.Duration) { stopChannel := make(misc.StopChannel) if timeout.Nanoseconds() < 0 { this.executeInternal(optimalPlan, q, stopChannel) } else { c := make(chan error, 1) go func() { this.executeInternal(optimalPlan, q, stopChannel) c <- nil }() select { case <-c: return case <-time.After(*timeout): clog.To(executor.CHANNEL, "simple executor timeout trigger") close(stopChannel) clog.To(executor.CHANNEL, "stop channel closed") } <-c q.Response().SendError(query.NewTimeoutError(timeout)) } }