1. 程式人生 > >Redis值notify.c閱讀

Redis值notify.c閱讀

keyspaceEventsStringToFlags:對傳入的字串引數進行分析, 給出相應的 flags 值

int keyspaceEventsStringToFlags(char *classes) {
    char *p = classes;
    int c, flags = 0;

    while((c = *p++) != '\0') {
        switch(c) {
        case 'A': flags |= REDIS_NOTIFY_ALL; break;
        case 'g': flags |= REDIS_NOTIFY_GENERIC; break;
        case '$': flags |= REDIS_NOTIFY_STRING; break;
        case 'l': flags |= REDIS_NOTIFY_LIST; break;
        case 's': flags |= REDIS_NOTIFY_SET; break;
        case 'h': flags |= REDIS_NOTIFY_HASH; break;
        case 'z': flags |= REDIS_NOTIFY_ZSET; break;
        case 'x': flags |= REDIS_NOTIFY_EXPIRED; break;
        case 'e': flags |= REDIS_NOTIFY_EVICTED; break;
        case 'K': flags |= REDIS_NOTIFY_KEYSPACE; break;
        case 'E': flags |= REDIS_NOTIFY_KEYEVENT; break;
        // 不能識別
        default: return -1;
        }
    }

    return flags;
}

keyspaceEventsFlagsToString:根據 flags 值還原設定這個 flags 所需的字串

sds keyspaceEventsFlagsToString(int flags) {
    sds res;

    res = sdsempty();
    if ((flags & REDIS_NOTIFY_ALL) == REDIS_NOTIFY_ALL) {
        res = sdscatlen(res,"A",1);
    } else {
        if (flags & REDIS_NOTIFY_GENERIC) res = sdscatlen(res,"g",1);
        if (flags & REDIS_NOTIFY_STRING) res = sdscatlen(res,"$",1);
        if (flags & REDIS_NOTIFY_LIST) res = sdscatlen(res,"l",1);
        if (flags & REDIS_NOTIFY_SET) res = sdscatlen(res,"s",1);
        if (flags & REDIS_NOTIFY_HASH) res = sdscatlen(res,"h",1);
        if (flags & REDIS_NOTIFY_ZSET) res = sdscatlen(res,"z",1);
        if (flags & REDIS_NOTIFY_EXPIRED) res = sdscatlen(res,"x",1);
        if (flags & REDIS_NOTIFY_EVICTED) res = sdscatlen(res,"e",1);
    }
    if (flags & REDIS_NOTIFY_KEYSPACE) res = sdscatlen(res,"K",1);
    if (flags & REDIS_NOTIFY_KEYEVENT) res = sdscatlen(res,"E",1);

    return res;
}

notifyKeyspaceEvent:釋出鍵事件通知

void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) {
    sds chan;
    robj *chanobj, *eventobj;
    int len = -1;
    char buf[24];

    /* If notifications for this class of events are off, return ASAP. */
    // 如果伺服器配置為不傳送 type 型別的通知,那麼直接返回
    if (!(server.notify_keyspace_events & type)) return;

    // 事件的名字
    eventobj = createStringObject(event,strlen(event));

    /* 
[email protected]
<db>__:<key> <event> notifications. */ // 傳送鍵空間通知 if (server.notify_keyspace_events & REDIS_NOTIFY_KEYSPACE) { // 構建頻道物件 chan = sdsnewlen("[email protected]",11); len = ll2string(buf,sizeof(buf),dbid); chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, "__:", 3); chan = sdscatsds(chan, key->ptr); chanobj = createObject(REDIS_STRING, chan); // 通過 publish 命令傳送通知 pubsubPublishMessage(chanobj, eventobj); // 釋放頻道物件 decrRefCount(chanobj); } /* [email protected]<db>__:<event> <key> notifications. */ // 傳送鍵事件通知 if (server.notify_keyspace_events & REDIS_NOTIFY_KEYEVENT) { // 構建頻道物件 chan = sdsnewlen("[email protected]",11); // 如果在前面傳送鍵空間通知的時候計算了 len ,那麼它就不會是 -1 // 這可以避免計算兩次 buf 的長度 if (len == -1) len = ll2string(buf,sizeof(buf),dbid); chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, "__:", 3); chan = sdscatsds(chan, eventobj->ptr); chanobj = createObject(REDIS_STRING, chan); // 通過 publish 命令傳送通知 pubsubPublishMessage(chanobj, key); // 釋放頻道物件 decrRefCount(chanobj); } // 釋放事件物件 decrRefCount(eventobj); }