From 55362ed76630f3e1ebec159a598f6a9fb5892cb1 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 16 Oct 2018 10:09:24 +0400 Subject: [PATCH] [pubsub] document design shortcomings (#2641) Refs https://github.com/tendermint/tendermint/issues/1811#issuecomment-427825250 --- libs/pubsub/pubsub.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/libs/pubsub/pubsub.go b/libs/pubsub/pubsub.go index c104439f8..18f098d87 100644 --- a/libs/pubsub/pubsub.go +++ b/libs/pubsub/pubsub.go @@ -9,6 +9,39 @@ // When some message is published, we match it with all queries. If there is a // match, this message will be pushed to all clients, subscribed to that query. // See query subpackage for our implementation. +// +// Due to the blocking send implementation, a single subscriber can freeze an +// entire server by not reading messages before it unsubscribes. To avoid such +// scenario, subscribers must either: +// +// a) make sure they continue to read from the out channel until +// Unsubscribe(All) is called +// +// s.Subscribe(ctx, sub, qry, out) +// go func() { +// for msg := range out { +// // handle msg +// // will exit automatically when out is closed by Unsubscribe(All) +// } +// }() +// s.UnsubscribeAll(ctx, sub) +// +// b) drain the out channel before calling Unsubscribe(All) +// +// s.Subscribe(ctx, sub, qry, out) +// defer func() { +// for range out { +// // drain out to make sure we don't block +// } +// s.UnsubscribeAll(ctx, sub) +// }() +// for msg := range out { +// // handle msg +// if err != nil { +// return err +// } +// } +// package pubsub import (