2012-04-09 18 views
7

estoy usando un canal pubsub Redis para enviar mensajes de un conjunto de procesos de trabajo a mi aplicación ASP.NET. Cuando se recibe un mensaje, mi aplicación reenvía el mensaje al navegador del cliente con SignalR.El mantenimiento de una suscripción Redis PubSub abierto con Booksleeve

Encontré this solution para mantener una conexión abierta a Redis, pero no tiene en cuenta las suscripciones cuando recrea la conexión.

Actualmente estoy manejo de mensajes PubSub Redis en mi archivo Global.asax:

public class Application : HttpApplication 
{ 
    protected void Application_Start() 
    { 
     var gateway = Resolve<RedisConnectionGateway>(); 
     var connection = gateway.GetConnection(); 
     var channel = connection.GetOpenSubscriberChannel(); 

     channel.PatternSubscribe("workers:job-done:*", OnExecutionCompleted); 
    } 

    /// <summary> 
    /// Handle messages received from workers through Redis.</summary> 
    private static void OnExecutionCompleted(string key, byte[] message) 
    { 
     /* forwarded the response to the client that requested it */ 
    } 
} 

El problema se produce cuando el RedisConnection actual se cierra por cualquier razón. La solución más simple sería desencadenar un evento de la clase RedisConnectionGateway cuando la conexión se ha restablecido y volver a suscribirse utilizando un nuevo RedisSubscriberChannel. Sin embargo, se perderán todos los mensajes publicados en el canal mientras se restablece la conexión.

¿Hay ejemplos de formas recomendadas para manejar esta situación?

+0

Mi solución de hecho devuelve una conexión Redis si ya está abierta, o abre una si no. Creo que en el "uso convencional" la conexión permanecerá abierta y no se perderá en su esquema PubSub. En el raro caso de que la conexión se cierre por algún motivo, obtendrá una nueva, y sí, los mensajes publicados en el canal mientras se restablece la conexión se perderán. Pero es por un tiempo muy corto, y no se supone que ocurra de manera regular. De todos modos, hagamos que el autor de BookSleeve resalte esto (CC @marcgravell). –

+0

@OferZelig gracias, pero '@ someone' no funciona a menos que ya estoy involucrado en el puesto de alguna manera; p –

+0

@MarcGravell Yo no sabía que; de todos modos: 1) ¿Cómo se puede comunicar con otro usuario SE para llamar su atención sobre algo? Quiero decir, dentro de un sitio de SE, no revisando el perfil y yendo a su blog o tal; 2) Puede implementar en SE una característica que identifica esto y alertas (un patrón xxx, donde xxx es un nombre de usuario SE conocido). ¡Gracias! –

Respuesta

7

Sí, si la conexión muere (inestabilidad de la red, re-masterización, lo que sea), entonces tendrá que volver a aplicar cualquier suscripción que haya realizado. Un evento para reconectar y volver a suscribir es bastante normal, y no muy diferente de lo que usamos aquí en SE/SO (excepto que normalmente rastreamos suscripciones más granulares, y tenemos un código de envoltura que maneja todo eso).

Sí, eventos publicados, mientras que su conexión se interrumpió han desaparecido. Esa es la naturaleza de redis pub/sub; no garantiza la entrega a clientes desconectados. O bien utilizar una herramienta que hace promesa de esto, o Redis uso para conducir una cola en lugar - empujar/apareciendo a/desde los extremos opuestos de una lista suele ser una alternativa razonable, y asegura que nada se pierde (siempre y cuando su software doesn' t soltarlo después de sacarlo de la lista). Si ayuda, tengo en mi lista una solicitud para agregar los métodos pop de bloqueo: destruyen totalmente la intención del multiplexor, pero tienen un uso genuino en algunos casos, así que no estoy en contra de agregarlos.

+0

No me importaría ver los métodos pop bloqueantes agregados a la API. En este momento, mi proyecto web usa Booksleeve, pero los trabajadores que brindan servicio a mi aplicación web dependen de ServiceStack.Redis para bloquear la API pop. –

+1

@Justin se agregará - con suerte esta semana –

+0

¡Eso sería increíble! ¡Gracias! –

Cuestiones relacionadas