Example #1
0
func (me *backend) Done(meta dingo.Meta) (err error) {
	var v int
	err = func() (err error) {
		var (
			ok  bool
			ids map[string]int
		)

		me.ridsLock.Lock()
		defer me.ridsLock.Unlock()

		if ids, ok = me.rids[meta.Name()]; ok {
			v, ok = ids[meta.ID()]
			delete(ids, meta.ID())
		}
		if !ok {
			err = errors.New("store id not found")
			return
		}

		return
	}()
	if err == nil {
		err = me.stores.Stop(v)
	}
	return
}
Example #2
0
func (me *broker) Send(id dingo.Meta, body []byte) (err error) {
	conn := me.pool.Get()
	defer conn.Close()

	_, err = conn.Do("LPUSH", fmt.Sprintf("%v.%v", _redisTaskQueue, id.Name()), body)
	if err != nil {
		return
	}

	return
}
Example #3
0
func (me *backend) Poll(meta dingo.Meta) (reports <-chan []byte, err error) {
	quit, done, idx := me.stores.New(0)

	me.ridsLock.Lock()
	defer me.ridsLock.Unlock()
	if v, ok := me.rids[meta.Name()]; ok {
		v[meta.ID()] = idx
	} else {
		me.rids[meta.Name()] = map[string]int{meta.ID(): idx}
	}

	r := make(chan []byte, 10)
	reports = r
	go me._store_routine_(quit, done, me.stores.Events(), r, meta)

	return
}
Example #4
0
func (me *broker) Send(id dingo.Meta, body []byte) (err error) {
	// acquire a channel
	ci, err := me.sender.Channel()
	if err != nil {
		return
	}
	defer me.sender.ReleaseChannel(ci)

	err = ci.Channel.Publish(
		"dingo.x.task", // name of exchange
		id.Name(),      // routing key
		false,          // mandatory
		false,          // immediate
		amqp.Publishing{
			DeliveryMode: amqp.Persistent,
			ContentType:  "text/json",
			Body:         body,
		},
	)
	if err != nil {
		return
	}

	// block until amqp.Channel.NotifyPublish
	select {
	case cf, ok := <-ci.Confirm:
		if !ok {
			err = errors.New(fmt.Sprintf("confirm channel is closed before receiving confirm: %v", id))
		}
		if !cf.Ack {
			err = errors.New(fmt.Sprintf("Unable to publish to server: %v", id))
		}
	}

	return
}
Example #5
0
func getConsumerTag(meta dingo.Meta) string {
	return fmt.Sprintf("dingo.consumer.%s.%s", meta.Name(), meta.ID())
}
Example #6
0
func getRoutingKey(meta dingo.Meta) string {
	return fmt.Sprintf("dingo.rkey.%s.%s", meta.Name(), meta.ID())
}
Example #7
0
func getQueueName(meta dingo.Meta) string {
	return fmt.Sprintf("dingo.q.%s.%s", meta.Name(), meta.ID())
}
Example #8
0
func (me *backend) Poll(meta dingo.Meta) (reports <-chan []byte, err error) {
	// bind to the queue for this task
	tag, qName, rKey := getConsumerTag(meta), getQueueName(meta), getRoutingKey(meta)
	quit, done, idx := me.stores.New(0)

	me.ridsLock.Lock()
	defer me.ridsLock.Unlock()
	if v, ok := me.rids[meta.Name()]; ok {
		v[meta.ID()] = idx
	} else {
		me.rids[meta.Name()] = map[string]int{meta.ID(): idx}
	}

	// acquire a free channel
	ci, err := me.receiver.Channel()
	if err != nil {
		return
	}
	var (
		dv <-chan amqp.Delivery
		r  chan []byte
	)
	defer func() {
		if err != nil {
			me.receiver.ReleaseChannel(ci)
		} else {
			go me._store_routine_(quit, done, me.stores.Events(), r, ci, dv, meta)
		}
	}()
	// declare a queue for this task
	_, err = ci.Channel.QueueDeclare(
		qName, // name of queue
		true,  // durable
		false, // auto-delete
		false, // exclusive
		false, // nowait
		nil,   // args
	)
	if err != nil {
		return
	}

	// bind queue to result-exchange
	err = ci.Channel.QueueBind(
		qName,            // name of queue
		rKey,             // routing key
		"dingo.x.result", // name of exchange
		false,            // nowait
		nil,              // args
	)
	if err != nil {
		return
	}

	dv, err = ci.Channel.Consume(
		qName, // name of queue
		tag,   // consumer Tag
		false, // autoAck
		false, // exclusive
		false, // noLocal
		false, // noWait
		nil,   // args
	)
	if err != nil {
		return
	}

	r = make(chan []byte, 10)
	reports = r
	return
}