Beispiel #1
0
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
}
Beispiel #2
0
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)
	}
}
Beispiel #3
0
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))
	}
}
Beispiel #4
0
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")
}