Beispiel #1
0
func TestPushed(t *testing.T) {
	pc, err := redistest.Dial()
	if err != nil {
		t.Fatalf("error connection to database, %v", err)
	}
	defer pc.Close()

	nc, err := net.Dial("tcp", ":6379")
	if err != nil {
		t.Fatal(err)
	}
	defer nc.Close()
	nc.SetReadDeadline(time.Now().Add(4 * time.Second))

	c := redis.PubSubConn{Conn: redis.NewConn(nc, 0, 0)}

	c.Subscribe("c1")
	expectPushed(t, c, "Subscribe(c1)", redis.Subscription{Kind: "subscribe", Channel: "c1", Count: 1})
	c.Subscribe("c2")
	expectPushed(t, c, "Subscribe(c2)", redis.Subscription{Kind: "subscribe", Channel: "c2", Count: 2})
	c.PSubscribe("p1")
	expectPushed(t, c, "PSubscribe(p1)", redis.Subscription{Kind: "psubscribe", Channel: "p1", Count: 3})
	c.PSubscribe("p2")
	expectPushed(t, c, "PSubscribe(p2)", redis.Subscription{Kind: "psubscribe", Channel: "p2", Count: 4})
	c.PUnsubscribe()
	expectPushed(t, c, "Punsubscribe(p1)", redis.Subscription{Kind: "punsubscribe", Channel: "p1", Count: 3})
	expectPushed(t, c, "Punsubscribe()", redis.Subscription{Kind: "punsubscribe", Channel: "p2", Count: 2})

	pc.Do("PUBLISH", "c1", "hello")
	expectPushed(t, c, "PUBLISH c1 hello", redis.Message{Channel: "c1", Data: []byte("hello")})

	c.Ping("hello")
	expectPushed(t, c, `Ping("hello")`, redis.Pong{"hello"})

	c.Conn.Send("PING")
	c.Conn.Flush()
	expectPushed(t, c, `Send("PING")`, redis.Pong{})
}
Beispiel #2
0
func TestPushed(t *testing.T) {
	pc, err := redis.DialDefaultServer()
	if err != nil {
		t.Fatalf("error connection to database, %v", err)
	}
	defer pc.Close()

	sc, err := redis.DialDefaultServer()
	if err != nil {
		t.Fatalf("error connection to database, %v", err)
	}
	defer sc.Close()

	c := redis.PubSubConn{Conn: sc}

	c.Subscribe("c1")
	expectPushed(t, c, "Subscribe(c1)", redis.Subscription{Kind: "subscribe", Channel: "c1", Count: 1})
	c.Subscribe("c2")
	expectPushed(t, c, "Subscribe(c2)", redis.Subscription{Kind: "subscribe", Channel: "c2", Count: 2})
	c.PSubscribe("p1")
	expectPushed(t, c, "PSubscribe(p1)", redis.Subscription{Kind: "psubscribe", Channel: "p1", Count: 3})
	c.PSubscribe("p2")
	expectPushed(t, c, "PSubscribe(p2)", redis.Subscription{Kind: "psubscribe", Channel: "p2", Count: 4})
	c.PUnsubscribe()
	expectPushed(t, c, "Punsubscribe(p1)", redis.Subscription{Kind: "punsubscribe", Channel: "p1", Count: 3})
	expectPushed(t, c, "Punsubscribe()", redis.Subscription{Kind: "punsubscribe", Channel: "p2", Count: 2})

	pc.Do("PUBLISH", "c1", "hello")
	expectPushed(t, c, "PUBLISH c1 hello", redis.Message{Channel: "c1", Data: []byte("hello")})

	c.Ping("hello")
	expectPushed(t, c, `Ping("hello")`, redis.Pong{Data: "hello"})

	c.Conn.Send("PING")
	c.Conn.Flush()
	expectPushed(t, c, `Send("PING")`, redis.Pong{})
}
Beispiel #3
0
func (this __red) Subscribe(messages ...interface{}) (notify chan interface{}, shutdown func(wait bool)) {
	log.Println("SUBSCRIBE")

	channels := []interface{}{}
	channelsMap := map[string]interface{}{}
	for _, message := range messages {
		switch message := message.(type) {

		default:
			_ = message
			panic("Unsupported message type")
		}
	}

	conn := this.__.(redis.Conn)
	psc := redis.PubSubConn{Conn: conn}

	err := psc.Subscribe(channels...)
	if err != nil {
		panic(err)
	}

	notify = make(chan interface{}, 1024)
	notifyInternal := make(chan interface{}, 1024)
	closeInternal := make(chan error, 1)

	go func() {
		defer func() {
			if rec := recover(); rec != nil {
				log.Println("PANIC ! RECEIVER:", rec, __red_stack())
				closeInternal <- errors.New(fmt.Sprint(rec))
			} else {
				log.Println("RECEIVER No more subscriptions")
				closeInternal <- nil
			}
		}()

		for {
			switch n := psc.Receive().(type) {
			case redis.Message:
				if m, ok := channelsMap[n.Channel]; ok {
					switch m := m.(type) {

					default:
						_ = m
						panic("Unsupported message type")
					}
				} else {
					// TODO
				}
			case redis.Subscription:
				if n.Count == 0 {
					return
				}
			}
		}
	}()

	var doneWG sync.WaitGroup
	doneWG.Add(1)
	go func() {
		defer func() {
			defer doneWG.Done()
			if rec := recover(); rec != nil {
				log.Println("PANIC ! PINGER:", rec, __red_stack())
				notify <- errors.New(fmt.Sprint(rec))
			} else {
				// TODO
				log.Println("PUBSUB | CLOSED")
			}
		}()
	Q:
		for {
			select {
			case err := <-closeInternal:
				notify <- err
				break Q
			case <-notifyInternal:
				// notify <- msg
			case <-time.After(__red_ops.PingPeriod):
				err := psc.Ping("")
				if err != nil {
					notify <- err
					break Q
				}
			}
		}
	}()

	shutdown = func(wait bool) {
		err := psc.Unsubscribe()
		if err != nil {
			panic(err)
		}
		if wait {
			doneWG.Wait()
		}
	}
	return
}