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 }
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 }
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 }
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 }
func getConsumerTag(meta dingo.Meta) string { return fmt.Sprintf("dingo.consumer.%s.%s", meta.Name(), meta.ID()) }
func getRoutingKey(meta dingo.Meta) string { return fmt.Sprintf("dingo.rkey.%s.%s", meta.Name(), meta.ID()) }
func getQueueName(meta dingo.Meta) string { return fmt.Sprintf("dingo.q.%s.%s", meta.Name(), meta.ID()) }
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 }