Skip to content

Commit 96efa27

Browse files
authored
feat: WithLocalPublication option to enable local only publishing on a topic (#481)
* feat: WithLocalPublication option to enable local only publishing on a topic * docs: improve comment on WithLocalPublication option
1 parent ca70228 commit 96efa27

File tree

3 files changed

+64
-3
lines changed

3 files changed

+64
-3
lines changed

pubsub.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ type Message struct {
221221
ID string
222222
ReceivedFrom peer.ID
223223
ValidatorData interface{}
224+
Local bool
224225
}
225226

226227
func (m *Message) GetFrom() peer.ID {
@@ -1066,7 +1067,7 @@ func (p *PubSub) handleIncomingRPC(rpc *RPC) {
10661067
continue
10671068
}
10681069

1069-
p.pushMsg(&Message{pmsg, "", rpc.from, nil})
1070+
p.pushMsg(&Message{pmsg, "", rpc.from, nil, false})
10701071
}
10711072
}
10721073

@@ -1165,7 +1166,9 @@ func (p *PubSub) checkSigningPolicy(msg *Message) error {
11651166
func (p *PubSub) publishMessage(msg *Message) {
11661167
p.tracer.DeliverMessage(msg)
11671168
p.notifySubs(msg)
1168-
p.rt.Publish(msg)
1169+
if !msg.Local {
1170+
p.rt.Publish(msg)
1171+
}
11691172
}
11701173

11711174
type addTopicReq struct {

topic.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ type ProvideKey func() (crypto.PrivKey, peer.ID)
215215
type PublishOptions struct {
216216
ready RouterReady
217217
customKey ProvideKey
218+
local bool
218219
}
219220

220221
type PubOpt func(pub *PublishOptions) error
@@ -307,7 +308,7 @@ func (t *Topic) Publish(ctx context.Context, data []byte, opts ...PubOpt) error
307308
}
308309
}
309310

310-
return t.p.val.PushLocal(&Message{m, "", t.p.host.ID(), nil})
311+
return t.p.val.PushLocal(&Message{m, "", t.p.host.ID(), nil, pub.local})
311312
}
312313

313314
// WithReadiness returns a publishing option for only publishing when the router is ready.
@@ -319,6 +320,18 @@ func WithReadiness(ready RouterReady) PubOpt {
319320
}
320321
}
321322

323+
// WithLocalPublication returns a publishing option to notify in-process subscribers only.
324+
// It prevents message publication to mesh peers.
325+
// Useful in edge cases where the msg needs to be only delivered to the in-process subscribers,
326+
// e.g. not to spam the network with outdated msgs.
327+
// Should not be used specifically for in-process pubsubing.
328+
func WithLocalPublication(local bool) PubOpt {
329+
return func(pub *PublishOptions) error {
330+
pub.local = local
331+
return nil
332+
}
333+
}
334+
322335
// WithSecretKeyAndPeerId returns a publishing option for providing a custom private key and its corresponding peer ID
323336
// This option is useful when we want to send messages from "virtual", never-connectable peers in the network
324337
func WithSecretKeyAndPeerId(key crypto.PrivKey, pid peer.ID) PubOpt {

topic_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,3 +1019,48 @@ func TestTopicRelayPublishWithKey(t *testing.T) {
10191019
}
10201020
}
10211021
}
1022+
1023+
func TestWithLocalPublication(t *testing.T) {
1024+
ctx, cancel := context.WithCancel(context.Background())
1025+
defer cancel()
1026+
1027+
const topic = "test"
1028+
1029+
hosts := getNetHosts(t, ctx, 2)
1030+
pubsubs := getPubsubs(ctx, hosts)
1031+
topics := getTopics(pubsubs, topic)
1032+
connectAll(t, hosts)
1033+
1034+
payload := []byte("pubsub smashes")
1035+
1036+
local, err := topics[0].Subscribe()
1037+
if err != nil {
1038+
t.Fatal(err)
1039+
}
1040+
1041+
remote, err := topics[1].Subscribe()
1042+
if err != nil {
1043+
t.Fatal(err)
1044+
}
1045+
1046+
err = topics[0].Publish(ctx, payload, WithLocalPublication(true))
1047+
if err != nil {
1048+
t.Fatal(err)
1049+
}
1050+
1051+
remoteCtx, cancel := context.WithTimeout(ctx, time.Millisecond*100)
1052+
defer cancel()
1053+
1054+
msg, err := remote.Next(remoteCtx)
1055+
if msg != nil || err == nil {
1056+
t.Fatal("unexpected msg")
1057+
}
1058+
1059+
msg, err = local.Next(ctx)
1060+
if err != nil {
1061+
t.Fatal(err)
1062+
}
1063+
if !msg.Local || !bytes.Equal(msg.Data, payload) {
1064+
t.Fatal("wrong message")
1065+
}
1066+
}

0 commit comments

Comments
 (0)