예제 #1
0
func TestPushed(t *testing.T) {
	pc := dialt(t)
	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")})
}
예제 #2
0
func main() {
	c, err := redis.Dial("tcp", ":6379")
	if err != nil {
		panic(err)
	}
	defer c.Close()

	psc := redis.PubSubConn{Conn: c}

	psc.Subscribe("example")
	psc.PSubscribe("p*")
	for {
		switch n := psc.Receive().(type) {
		case redis.Message:
			fmt.Printf("Message: %s %s\n", n.Channel, n.Data)
		case redis.PMessage:
			fmt.Printf("PMessage: %s %s %s\n", n.Pattern, n.Channel, n.Data)
		case redis.Subscription:
			fmt.Printf("Subscription: %s %s %d\n", n.Kind, n.Channel, n.Count)
			if n.Count == 0 {
				return
			}
		case error:
			fmt.Printf("error: %v\n", n)
			return
		}
	}
}
예제 #3
0
func main3() {
	//INIT OMIT
	c, err := redis.Dial("tcp", ":6379")
	if err != nil {
		panic(err)
	}
	defer c.Close()

	//set
	c.Do("SET", "message1", "Hello World")

	//get
	world, err := redis.String(c.Do("GET", "message1"))
	if err != nil {
		fmt.Println("key not found")
	}

	fmt.Println(world)
	//ENDINIT OMIT

	psc := redis.PubSubConn{c}
	psc.PSubscribe("bigbluebutton:to-bbb-apps:system")
	for {
		switch v := psc.Receive().(type) {
		case redis.Message:
			fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
		case redis.PMessage:
			fmt.Printf("PMessage: %s %s %s\n", v.Pattern, v.Channel, v.Data)
		case redis.Subscription:
			fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
		case error:
			fmt.Printf("error: %v\n", v)
		}
	}
}
예제 #4
0
// Monitor sentinel
func MonitorSentinel() {
	redisConn := gRedisPool.Get()
	defer redisConn.Close()

	psc := redis.PubSubConn{redisConn}
	psc.PSubscribe("*")
	runflag := true
	for runflag {
		switch v := psc.Receive().(type) {
		case redis.Message:
			log.Infof("Type Message>>channel %s, message: %s", v.Channel, v.Data)
		case redis.Subscription:
			log.Infof("Type Subscribe>>channel %s, kind %s, count %d", v.Channel, v.Kind, v.Count)
			gRecoveryChan <- RECOVERY_TYPE_REDIS
		case error:
			log.Error("MonitorSentinel ERROR")
			runflag = false
			// Should re psubscrebe
		case redis.PMessage:
			log.Infof("Type PMessage>>channel %s, pattern %s, data %s", v.Channel, v.Pattern, v.Data)
			ParsePMessage(v)
		default:
			log.Warnf("Unkown Message Type of psubscribe")
		}
	}
}
예제 #5
0
파일: input.go 프로젝트: swan-go/heka-redis
func (rpsi *RedisPubSubInput) Run(ir pipeline.InputRunner, h pipeline.PluginHelper) error {
	var (
		dRunner pipeline.DecoderRunner
		decoder pipeline.Decoder
		pack    *pipeline.PipelinePack
		e       error
		ok      bool
	)
	// Get the InputRunner's chan to receive empty PipelinePacks
	packSupply := ir.InChan()

	if rpsi.conf.DecoderName != "" {
		if dRunner, ok = h.DecoderRunner(rpsi.conf.DecoderName, fmt.Sprintf("%s-%s", ir.Name(), rpsi.conf.DecoderName)); !ok {
			return fmt.Errorf("Decoder not found: %s", rpsi.conf.DecoderName)
		}
		decoder = dRunner.Decoder()
	}

	//Connect to the channel
	psc := redis.PubSubConn{Conn: rpsi.conn}
	psc.PSubscribe(rpsi.conf.Channel)

	for {
		switch n := psc.Receive().(type) {
		case redis.PMessage:
			// Grab an empty PipelinePack from the InputRunner
			pack = <-packSupply
			pack.Message.SetType("redis_pub_sub")
			pack.Message.SetLogger(n.Channel)
			pack.Message.SetPayload(string(n.Data))
			pack.Message.SetTimestamp(time.Now().UnixNano())
			var packs []*pipeline.PipelinePack
			if decoder == nil {
				packs = []*pipeline.PipelinePack{pack}
			} else {
				packs, e = decoder.Decode(pack)
			}
			if packs != nil {
				for _, p := range packs {
					ir.Inject(p)
				}
			} else {
				if e != nil {
					ir.LogError(fmt.Errorf("Couldn't parse Redis message: %s", n.Data))
				}
				pack.Recycle(nil)
			}
		case redis.Subscription:
			ir.LogMessage(fmt.Sprintf("Subscription: %s %s %d\n", n.Kind, n.Channel, n.Count))
			if n.Count == 0 {
				return errors.New("No channel to subscribe")
			}
		case error:
			fmt.Printf("error: %v\n", n)
			return n
		}
	}

	return nil
}
예제 #6
0
func SubCommonMsg() error {
	r := Redix[_SubCommonMsg]
	RedixMu[_SubCommonMsg].Lock()
	defer RedixMu[_SubCommonMsg].Unlock()

	psc := redis.PubSubConn{Conn: r}
	err := psc.PSubscribe(SubCommonMsgKey)
	if err != nil {
		return err
	}
	ch := make(chan redis.PMessage, 128)
	go func() {
		defer psc.Close()
		for {
			data := psc.Receive()
			switch m := data.(type) {
			case redis.PMessage:
				ch <- m
			case redis.Subscription:
				if m.Count == 0 {
					glog.Fatalf("Subscription: %s %s %d, %v\n", m.Kind, m.Channel, m.Count, m)
					return
				}
			case error:
				glog.Errorf("[modifypwd|redis] sub of error: %v\n", m)
				return
			}
		}
	}()
	go HandleCommonMsg(ch)
	return nil
}
예제 #7
0
// getKeyEventChannel returns a channel that sends events for key changes in
// Redis.
func (r *RedisRTC) getKeyEventChannel(channelOrPattern string, isPattern bool) (<-chan string, error) {
	// Listen for changes on the queue continously.
	psc := redis.PubSubConn{Conn: r.redisPool.Get()}

	subscribe := func() error {
		if isPattern {
			return psc.PSubscribe(channelOrPattern)
		} else {
			return psc.Subscribe(channelOrPattern)
		}
	}

	// Subscribe to the key events
	if err := subscribe(); err != nil {
		return nil, err
	}

	readyCh := make(chan bool)
	ret := make(chan string)
	go func() {
		for {
		Loop:
			for {
				switch v := psc.Receive().(type) {
				case redis.PMessage:
					ret <- string(v.Data)
				case redis.Message:
					ret <- string(v.Data)
				case redis.Subscription:
					if readyCh != nil {
						readyCh <- true
						close(readyCh)
					}
				case error:
					glog.Errorf("Error waiting for key events: %s", v)
					glog.Infof("Reconnecting.")
					util.Close(psc)
					break Loop
				}
			}

			readyCh = nil
			psc = redis.PubSubConn{Conn: r.redisPool.Get()}
			if err := subscribe(); err != nil {
				glog.Errorf("Error re-connecting: %s", err)
				time.Sleep(time.Second)
			}
		}
	}()
	<-readyCh

	return ret, nil
}
예제 #8
0
파일: io.go 프로젝트: heroku/busl
// NewReader creates a new redis channel reader
func NewReader(key string) (io.ReadCloser, error) {
	if !NewRedisRegistrar().IsRegistered(key) {
		return nil, ErrNotRegistered
	}

	psc := redis.PubSubConn{Conn: redisPool.Get()}
	channel := channel(key)
	psc.PSubscribe(channel.wildcardID())

	rd := &reader{
		channel: channel,
		psc:     psc,
		mutex:   &sync.Mutex{}}

	return rd, nil
}
예제 #9
0
func myRedisSubscriptions() (<-chan RedisMsg, <-chan RedisMsg) {

	// set up structures and channels to stream events out on
	scoreUpdates := make(chan RedisMsg)
	detailUpdates := make(chan RedisMsg)

	// get a new redis connection from pool.
	// since this is the first time the app tries to do something with redis,
	// die if we can't get a valid connection, since something is probably
	// configured wrong.
	conn := redisPool.Get()
	_, err := conn.Do("PING")
	if err != nil {
		log.Fatal("Could not connect to Redis, check your configuration.")
	}

	// subscribe to and handle streams
	psc := redis.PubSubConn{conn}
	psc.Subscribe("stream.score_updates")
	psc.PSubscribe("stream.tweet_updates.*")

	go func() {
		for {
			switch v := psc.Receive().(type) {
			case redis.Message:
				//fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
				scoreUpdates <- RedisMsg{v.Channel, v.Data} //string(v.Data)
			case redis.PMessage:
				//fmt.Printf("pattern: %s, channel: %s, data: %s\n", v.Pattern, v.Channel, v.Data)
				//TODO: at some point we might need to also match the pattern here for kiosk mode
				detailUpdates <- RedisMsg{v.Channel, v.Data}
			case error:
				log.Println("redis subscribe connection errored?@&*(#)akjd")
				// probable cause is connection was closed, but force close just in case
				conn.Close()

				log.Println("attempting to get a new one in 5 seconds...")
				time.Sleep(5 * time.Second)
				conn = redisPool.Get()
			}
		}
	}()

	return scoreUpdates, detailUpdates
}
예제 #10
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{})
}
예제 #11
0
// Applications can receive pushed messages from one goroutine and manage subscriptions from another goroutine.
func ExamplePubSubConn() {
	c, err := dial()
	if err != nil {
		panic(err)
	}
	defer c.Close()
	var wg sync.WaitGroup
	wg.Add(2)

	psc := redis.PubSubConn{Conn: c}

	// This goroutine receives and prints pushed notifications from the server.
	// The goroutine exits when the connection is unsubscribed from all
	// channels or there is an error.
	go func() {
		defer wg.Done()
		for {
			switch n := psc.Receive().(type) {
			case redis.Message:
				fmt.Printf("Message: %s %s\n", n.Channel, n.Data)
			case redis.PMessage:
				fmt.Printf("PMessage: %s %s %s\n", n.Pattern, n.Channel, n.Data)
			case redis.Subscription:
				fmt.Printf("Subscription: %s %s %d\n", n.Kind, n.Channel, n.Count)
				if n.Count == 0 {
					return
				}
			case error:
				fmt.Printf("error: %v\n", n)
				return
			}
		}
	}()

	// This goroutine manages subscriptions for the connection.
	go func() {
		defer wg.Done()

		psc.Subscribe("example")
		psc.PSubscribe("p*")

		// The following function calls publish a message using another
		// connection to the Redis server.
		publish("example", "hello")
		publish("example", "world")
		publish("pexample", "foo")
		publish("pexample", "bar")

		// Unsubscribe from all connections. This will cause the receiving
		// goroutine to exit.
		psc.Unsubscribe()
		psc.PUnsubscribe()
	}()

	wg.Wait()

	// Output:
	// Subscription: subscribe example 1
	// Subscription: psubscribe p* 2
	// Message: example hello
	// Message: example world
	// PMessage: p* pexample foo
	// PMessage: p* pexample bar
	// Subscription: unsubscribe example 1
	// Subscription: punsubscribe p* 0
}
예제 #12
0
func main() {
	flag.Parse()

	redisPool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", *redisAddress)

		if err != nil {
			return nil, err
		}

		return c, err
	}, *maxConnections)

	defer redisPool.Close()

	/*
		c, err := redis.Dial("tcp", ":6379")
		if err != nil {
			panic(err)
		}
		defer c.Close()
	*/

	var wg sync.WaitGroup
	wg.Add(2)

	//	psc := redis.PubSubConn{Conn: c}
	psc := redis.PubSubConn{Conn: redisPool.Get()}

	// This goroutine receives and prints pushed notifications from the server.
	// The goroutine exits when the connection is unsubscribed from all
	// channels or there is an error.
	go func() {
		defer wg.Done()
		for {
			switch n := psc.Receive().(type) {
			case redis.Message:
				fmt.Printf("Message: %s %s\n", n.Channel, n.Data)
			case redis.PMessage:
				fmt.Printf("PMessage: %s %s %s\n", n.Pattern, n.Channel, n.Data)
			case redis.Subscription:
				fmt.Printf("Subscription: %s %s %d\n", n.Kind, n.Channel, n.Count)
				if n.Count == 0 {
					return
				}
			case error:
				fmt.Printf("error: %v\n", n)
				return
			}
		}
	}()

	// This goroutine manages subscriptions for the connection.
	go func() {
		defer wg.Done()

		psc.Subscribe("example")
		psc.PSubscribe("p*")
		psc.PSubscribe("bigbluebutton:to-bbb-apps:system")

		// The following function calls publish a message using another
		// connection to the Redis server.
		publish("example", "hello")
		publish("example", "world")
		publish("pexample", "foo")
		publish("pexample", "bar")

		// Unsubscribe from all connections. This will cause the receiving
		// goroutine to exit.
		psc.Unsubscribe()
		//psc.PUnsubscribe()
	}()

	wg.Wait()

	// Output:
	// Subscription: subscribe example 1
	// Subscription: psubscribe p* 2
	// Message: example hello
	// Message: example world
	// PMessage: p* pexample foo
	// PMessage: p* pexample bar
	// Subscription: unsubscribe example 1
	// Subscription: punsubscribe p* 0
}
예제 #13
0
func main() {
	debug := false //bool for now we can make it more verbose if needed
	handleFlags(&debug)
	//setup the pool for the connections
	var pool = &redis.Pool{
		MaxIdle:     common.REDIS_MAX_POOL_IDLE,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", common.REDIS_ADDRESS+":"+common.REDIS_PORT)
			if err != nil {
				return nil, err
			}
			return c, err
		}, //end dial
	} //end pool
	common.LogEvent(debug, "Created new Redis Pool.")

	zmqCTX, err := zmq.NewContext()
	if err != nil {
		panic(err)
	}
	defer zmqCTX.Close()

	common.LogEvent(debug, "Created new ZeroMQ Context")

	trackerZMQPUB, err := zmqCTX.Socket(zmq.Pub)
	if err != nil {
		panic(err)
	}
	defer trackerZMQPUB.Close()

	common.LogEvent(debug, "Created new ZeroMQ Pub Socket.")

	trackerZMQREP, err := zmqCTX.Socket(zmq.Rep)
	if err != nil {
		panic(err)
	}
	defer trackerZMQREP.Close()

	common.LogEvent(debug, "Created new ZeroMQ Rep Socket.")

	//bind the publisher socket to the pub port for zmq
	if err = trackerZMQPUB.Bind(common.ZMQ_SOCKET_PROTOCOL + common.ZMQ_TRACKER_PUB_IP_ADDRESS + ":" + common.ZMQ_TRACKER_PUB_PORT); err != nil {
		panic(err)
	}

	//bind the reply socket to the rep port for zmq
	if err = trackerZMQREP.Bind(common.ZMQ_SOCKET_PROTOCOL + common.ZMQ_TRACKER_REP_IP_ADDRESS + ":" + common.ZMQ_TRACKER_REP_PORT); err != nil {
		panic(err)
	}
	fmt.Println(pool.ActiveCount())

	conn := pool.Get()
	defer conn.Close()

	common.LogEvent(debug, "Created a new pool connection")

	psc := redis.PubSubConn{conn}           //setup a PubSubConn passing our previous connection to it
	psc.PSubscribe(common.REDIS_SUB_STRING) //subscribe to the ASMS::* string, which is everything
	fmt.Println(pool.ActiveCount())
	//channelRegistry := make(map[string]chan string) //create a channelRegistry to track the channels being created below for each spawned goroutine

	go handleReply(pool, trackerZMQREP) //spawn a go routine for handleReply this takes care of handling responding to server loads
	common.LogEvent(debug, "Spawned new goprocess for handleReply.")

	for {
		common.LogEvent(debug, "Receieved a new redis data item.")
		switch v := psc.Receive().(type) {
		case redis.PMessage:
			common.LogEvent(debug, "Redis data item is of type Message.")
			channelSplit := strings.Split(v.Channel, common.ACCOUNT_IDS_SEP) //take the channel string contained in the reply struct, split it.
			switch channelSplit[1] {                                         // the key is laid out as ASMS::<Message>/<Receipt>/<UpdateDevice>::....
			case "Message":
				go handleMessage(pool, trackerZMQPUB, v.Data)
				common.LogEvent(debug, "Spawned new goprocess for handleMessage.")
			case "Receipt":
				go handleReceipt(pool, trackerZMQPUB, v.Data)
				common.LogEvent(debug, "Spawned new goprocess for handleReceipt.")
			case "UpdateDevice":
				go handleUpdateDevice(pool, trackerZMQPUB, v.Data)
				common.LogEvent(debug, "Spawned new goprocess for handleUpdateDevice.")
			default:
				fmt.Println("tracker.go: Recieved an unexpected request.")
			} //end switch channelSplit[1]
		case redis.Subscription:
			//dont know what to say!!!
			fmt.Println("I guess we will always get here on start,since we recieve back from the redis server?")
		case error:
			panic(v)
		} //end switch v:=
	} //end for
} //end main