本文整理汇总了Golang中github.com/garyburd/redigo/redis.PubSubConn.Close方法的典型用法代码示例。如果您正苦于以下问题:Golang PubSubConn.Close方法的具体用法?Golang PubSubConn.Close怎么用?Golang PubSubConn.Close使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/garyburd/redigo/redis.PubSubConn
的用法示例。
在下文中一共展示了PubSubConn.Close方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: SubCommonMsg
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
}
示例2: respondToPings
// respondToPings continuously listens for pings from other worker pools and
// immediately responds with a pong. It will only return if there is an error.
func (p *Pool) respondToPings() error {
pong := redisPool.Get()
ping := redis.PubSubConn{redisPool.Get()}
defer func() {
pong.Close()
ping.Close()
}()
// Subscribe to the ping key for this pool to receive pings.
if err := ping.Subscribe(p.pingKey()); err != nil {
return err
}
for {
// Whenever we recieve a ping, reply immediately with a pong by
// publishing to the pong key for this pool.
switch reply := ping.Receive().(type) {
case redis.Message:
if _, err := pong.Do("PUBLISH", p.pongKey(), 0); err != nil {
return err
}
case error:
err := reply.(error)
return err
}
time.Sleep(1 * time.Millisecond)
}
}
示例3: SubModifiedPasswd
func SubModifiedPasswd() error {
r := Redix[_SubModifiedPasswd]
RedixMu[_SubModifiedPasswd].Lock()
defer RedixMu[_SubModifiedPasswd].Unlock()
psc := redis.PubSubConn{Conn: r}
err := psc.Subscribe(SubModifiedPasswdKey)
if err != nil {
return err
}
ch := make(chan []byte, 128)
go func() {
defer psc.Close()
for {
data := psc.Receive()
switch n := data.(type) {
case redis.Message:
ch <- n.Data
case redis.Subscription:
if n.Count == 0 {
glog.Fatalf("Subscription: %s %s %d, %v\n", n.Kind, n.Channel, n.Count, n)
return
}
case error:
glog.Errorf("[modifypwd|redis] sub of error: %v\n", n)
return
}
}
}()
go HandleModifiedPasswd(ch)
return nil
}
示例4: pingAndPurgeIfNeeded
// pingAndPurgeIfNeeded pings other by publishing to others ping key. If it
// does not receive a pong reply within some amount of time, it will
// assume the pool is stale and purge it.
func (p *Pool) pingAndPurgeIfNeeded(other *Pool) error {
ping := redisPool.Get()
pong := redis.PubSubConn{redisPool.Get()}
// Listen for pongs by subscribing to the other pool's pong key
pong.Subscribe(other.pongKey())
// Ping the other pool by publishing to its ping key
ping.Do("PUBLISH", other.pingKey(), 1)
// Use a select statement to either receive the pong or timeout
pongChan := make(chan interface{})
errChan := make(chan error)
go func() {
defer func() {
pong.Close()
ping.Close()
}()
select {
case <-p.exit:
return
default:
}
for {
reply := pong.Receive()
switch reply.(type) {
case redis.Message:
// The pong was received
pongChan <- reply
return
case error:
// There was some unexpected error
err := reply.(error)
errChan <- err
return
}
}
}()
timeout := time.After(p.config.StaleTimeout)
select {
case <-pongChan:
// The other pool responded with a pong
return nil
case err := <-errChan:
// Received an error from the pubsub conn
return err
case <-timeout:
// The pool is considered stale and should be purged
t := newTransaction()
other.RLock()
otherId := other.id
other.RUnlock()
t.purgeStalePool(otherId)
if err := t.exec(); err != nil {
return err
}
}
return nil
}
示例5: RedisSub
func RedisSub(key string) (chan interface{}, redis.PubSubConn, error) {
mq := make(chan interface{}, Conf.RedisMQSize)
c := redisPool.Get()
defer c.Close()
pc, err := redis.Dial(Conf.RedisNetwork, Conf.RedisAddr)
if err != nil {
Log.Printf("redis.Dial(\"%s\", \"%s\") failed (%s)", Conf.RedisNetwork, Conf.RedisAddr, err.Error())
return nil, redis.PubSubConn{}, err
}
psc := redis.PubSubConn{pc}
// check queue
err = redisQueue(c, key, mq)
if err != nil {
Log.Printf("redisQueue failed (%s)", err.Error())
return nil, redis.PubSubConn{}, err
}
// subscribe
psc.Subscribe(key)
if _, ok := psc.Receive().(redis.Subscription); !ok {
Log.Printf("init sub must redis.Subscription")
return nil, redis.PubSubConn{}, fmt.Errorf("first sub must init")
}
// double check
err = redisQueue(c, key, mq)
if err != nil {
Log.Printf("redisQueue failed (%s)", err.Error())
return nil, redis.PubSubConn{}, err
}
go func() {
// DEBUG
Log.Printf("redis routine start")
// DEBUG
defer Log.Printf("redis routine exit")
defer psc.Close()
for {
switch n := psc.Receive().(type) {
case redis.Message:
mq <- string(n.Data)
case redis.PMessage:
mq <- string(n.Data)
case redis.Subscription:
// DEBUG
Log.Printf("redis UnSubscrption")
return
case error:
Log.Printf("psc.Receive() failed (%s)", n.Error())
mq <- n
return
}
}
}()
return mq, psc, nil
}
示例6: updateEvents
func (c *Cache) updateEvents() {
var disconnected bool = false
connect:
for {
rconn, err := redis.DialTimeout("tcp", GetConfig().RedisAddress, redisConnectionTimeout, 0, 200*time.Millisecond)
if err != nil {
disconnected = true
time.Sleep(50 * time.Millisecond)
continue
}
if _, err = rconn.Do("PING"); err != nil {
// Doing a PING after (re-connection) prevents cases where redis
// is currently loading the dataset and is still not ready.
// "LOADING Redis is loading the dataset in memory"
rconn.Close()
log.Info("Redis is loading the dataset in memory")
time.Sleep(500 * time.Millisecond)
continue
}
log.Info("Redis connected, subscribing pubsub.")
psc := redis.PubSubConn{Conn: rconn}
psc.Subscribe(FILE_UPDATE)
psc.Subscribe(MIRROR_UPDATE)
psc.Subscribe(MIRROR_FILE_UPDATE)
if disconnected == true {
// This is a way to keep the cache active while disconnected
// from redis but still clear the cache (possibly outdated)
// after a successful reconnection.
disconnected = false
c.Clear()
}
for {
switch v := psc.Receive().(type) {
case redis.Message:
//if os.Getenv("DEBUG") != "" {
// fmt.Printf("Redis message on channel %s: message: %s\n", v.Channel, v.Data)
//}
c.handleMessage(v.Channel, v.Data)
case redis.Subscription:
if os.Getenv("DEBUG") != "" {
log.Debug("Redis subscription event on channel %s: %s %d\n", v.Channel, v.Kind, v.Count)
}
case error:
log.Error("UpdateEvents error: %s", v)
psc.Close()
rconn.Close()
time.Sleep(50 * time.Millisecond)
disconnected = true
goto connect
}
}
}
}
示例7: subscribeChannel
func (r *RedisBackend) subscribeChannel(key string, msgs chan string) {
var wg sync.WaitGroup
redisPool := redis.Pool{
MaxIdle: 1,
IdleTimeout: 0,
Dial: func() (redis.Conn, error) {
return redis.DialTimeout("tcp", r.RedisHost, time.Second, 0, 0)
},
// test every connection for now
TestOnBorrow: r.testOnBorrow,
}
for {
conn := redisPool.Get()
// no defer, doesn't return
if err := conn.Err(); err != nil {
conn.Close()
log.Printf("ERROR: %v\n", err)
time.Sleep(5 * time.Second)
continue
}
wg.Add(1)
psc := redis.PubSubConn{Conn: conn}
go func() {
defer wg.Done()
for {
switch n := psc.Receive().(type) {
case redis.Message:
msg := string(n.Data)
msgs <- msg
case error:
psc.Close()
log.Printf("ERROR: %v\n", n)
return
}
}
}()
wg.Add(1)
go func() {
defer wg.Done()
psc.Subscribe(key)
log.Printf("Monitoring for config changes on channel: %s\n", key)
}()
wg.Wait()
conn.Close()
}
}
示例8: updateEvents
func (p *Pubsub) updateEvents() {
var disconnected bool = false
connect:
for {
rconn := p.r.pool.Get()
if _, err := rconn.Do("PING"); err != nil {
disconnected = true
rconn.Close()
if RedisIsLoading(err) {
// Doing a PING after (re-connection) prevents cases where redis
// is currently loading the dataset and is still not ready.
log.Warning("Redis is still loading the dataset in memory")
}
time.Sleep(500 * time.Millisecond)
continue
}
log.Info("Subscribing pubsub")
psc := redis.PubSubConn{Conn: rconn}
psc.Subscribe(CLUSTER)
psc.Subscribe(FILE_UPDATE)
psc.Subscribe(MIRROR_UPDATE)
psc.Subscribe(MIRROR_FILE_UPDATE)
if disconnected == true {
// This is a way to keep the cache active while disconnected
// from redis but still clear the cache (possibly outdated)
// after a successful reconnection.
disconnected = false
p.handleMessage(string(PUBSUB_RECONNECTED), nil)
}
for {
switch v := psc.Receive().(type) {
case redis.Message:
//log.Debug("Redis message on channel %s: message: %s", v.Channel, v.Data)
p.handleMessage(v.Channel, v.Data)
case redis.Subscription:
log.Debug("Redis subscription on channel %s: %s (%d)", v.Channel, v.Kind, v.Count)
case error:
log.Error("Pubsub disconnected: %s", v)
psc.Close()
rconn.Close()
time.Sleep(50 * time.Millisecond)
disconnected = true
goto connect
}
}
}
}
示例9: ListenToRedis
func (s *Socket) ListenToRedis() {
rConn := redis.PubSubConn{Conn: RedisPool.Get()}
defer rConn.Close()
rConn.Subscribe(s.redisChannels()...)
var (
message *Message
err error
)
for {
switch event := rConn.Receive().(type) {
case redis.Message:
err = json.Unmarshal(event.Data, &message)
if err != nil {
s.logMsg("[SECURITY] Redis message isn't JSON: %s", event.Data)
continue
}
switch message.Event {
case "message":
if message.IssuerID == s.ID {
// Message was sent by this connection, ignore.
continue
}
s.logMsg("Received message from redis on '%s'", message.Channel)
websocket.JSON.Send(s.ws, &message)
case "close":
if message.IssuerID == s.ID {
rConn.PUnsubscribe(s.redisChannels()...)
break
}
}
case error:
rConn.Close()
rConn = redis.PubSubConn{Conn: RedisPool.Get()}
rConn.Subscribe(s.redisChannels()...)
}
}
}
示例10: SubUserState
func SubUserState() (<-chan []byte, error) {
r := Redix[_SubLoginState].Get()
psc := redis.PubSubConn{Conn: r}
psc.Subscribe(SubKey)
ch := make(chan []byte, 128)
// 单独处理Subscribe后的第一个消息(即返回值),用于保证在已监听到SubKey后,
// 本函数返回,主函数继续载入已有的设备在线列表。用于避免Msgbus和Comet都刚刚
// 启动时,Comet删除上次的旧设备列表和立刻登录的新设备之间的时间窗口中,Msgbus
// 由于异步监听SubKey,导致先载入了旧的列表,后监听到SubKey,导致遗漏了Comet
// 发出的删除旧列表通知。
data := psc.Receive()
switch n := data.(type) {
case redis.Subscription:
if n.Count == 0 {
glog.Fatalf("Subscription: %s %s %d, %v\n", n.Kind, n.Channel, n.Count, n)
}
case error:
glog.Errorf("subscribe on LoginState error: %v\n", n)
return nil, n
}
go func() {
defer psc.Close()
for {
data := psc.Receive()
switch n := data.(type) {
case redis.Message:
ch <- n.Data
//if glog.V(1) {
// glog.Infof("Message: %s %s\n", n.Channel, n.Data)
//}
case error:
glog.Errorf("error: %v\n", n)
return
}
}
}()
return ch, nil
}
示例11: GetCerts
// GetCerts gets a list of certs from the database, or another cluster member.
func (r *Redis) GetCerts() ([]core.CertBundle, error) {
if database.CentralStore {
return database.GetCerts()
}
conn := pool.Get()
defer conn.Close()
// get known members(other than me) to 'poll' for certs
members, _ := redis.Strings(conn.Do("SMEMBERS", "members"))
if len(members) == 0 {
// should only happen on new cluster
// assume i'm ok to be master so don't reset imported certs
config.Log.Trace("[cluster] - Assuming OK to be master, using certs from my database...")
return common.GetCerts()
}
for i := range members {
if members[i] == self {
// if i'm in the list of members, new requests should have failed while `waitForMembers`ing
config.Log.Trace("[cluster] - Assuming I was in sync, using certs from my database...")
return common.GetCerts()
}
}
c, err := redis.DialURL(config.ClusterConnection, redis.DialConnectTimeout(15*time.Second), redis.DialPassword(config.ClusterToken))
if err != nil {
return nil, fmt.Errorf("Failed to reach redis for certs subscriber - %v", err)
}
defer c.Close()
message := make(chan interface{})
subconn := redis.PubSubConn{c}
// subscribe to channel that certs will be published on
if err := subconn.Subscribe("certs"); err != nil {
return nil, fmt.Errorf("Failed to reach redis for certs subscriber - %v", err)
}
defer subconn.Close()
// listen always
go func() {
for {
message <- subconn.Receive()
}
}()
// todo: maybe use ttl?
// timeout is how long to wait for the listed members to come back online
timeout := time.After(time.Duration(20) * time.Second)
// loop attempts for timeout, allows last dead members to start back up
for {
select {
case <-timeout:
return nil, fmt.Errorf("Timed out waiting for certs from %v", strings.Join(members, ", "))
default:
// request certs from each member until successful
for _, member := range members {
// memberTimeout is how long to wait for a member to respond with list of certs
memberTimeout := time.After(3 * time.Second)
// ask a member for its certs
config.Log.Trace("[cluster] - Attempting to request certs from %v...", member)
_, err := conn.Do("PUBLISH", "portal", fmt.Sprintf("get-certs %s", member))
if err != nil {
return nil, err
}
// wait for member to respond
for {
select {
case <-memberTimeout:
config.Log.Debug("[cluster] - Timed out waiting for certs from %v", member)
goto nextCertMember
case msg := <-message:
switch v := msg.(type) {
case redis.Message:
config.Log.Trace("[cluster] - Received message on 'certs' channel")
var certs []core.CertBundle
err = parseBody(v.Data, &certs)
if err != nil {
return nil, fmt.Errorf("Failed to marshal certs - %v", err.Error())
}
config.Log.Trace("[cluster] - Certs from cluster: %#v\n", certs)
return certs, nil
case error:
return nil, fmt.Errorf("Subscriber failed to receive certs - %v", v.Error())
}
}
}
nextCertMember:
}
}
}
}