Why Nostr? What is Njump?
2023-08-29 15:41:38

Nostr GitHub Connect on Nostr: Issue: Title: Breaking Change Request: redesign updateSub's API Author: Water Blower ...

Issue: https://github.com/BlowaterNostr/nostr.ts/issues/16
Title: Breaking Change Request: redesign updateSub's API
Author:
# Problem
Consider
```ts
const subID = "xxx"
const stream1 = await pool.newSub(subID, {...});
const stream2 = await pool.updateSub(subID, {...});
```
Currently, `stream1` and `stream2` are the same reference. Updating a subscription won't kill the channel created by the previous subscription.

This is an abstraction invented by `nostr.ts` since nostr protocol does not have the concept of updating an existing subscription. Our implementation close the previous subscription and creates a new subscription with the same name.

This design looks nice and convenient at first, but after several months' practice, I find this API behavior might not be desireable.

1. Hard to debug
In Blowater's production, we encountered dangling promises or starvation of channels. https://github.com/BlowaterNostr/blowater/issues/115
The root cause is still unknown but this API design should be related because Blowater did not have this problem before introducing `updateSub`

2. Unclear responsibility for channel consumers
In a real world situation, `stream1` and `stream2` are likely to be constructed in different places of the code and in different time. Since `stream1` and `stream2` are the same reference. Their consumers effectly are racing to read from the same channel which might not be desired and might cause surprising data loss from individual consumer's perspective.

3. Suprising Data for consumers
Following No.2, the reader of `stream1` might be surprised that it gets data which doesn't match its original filter.

# Proposal
1. Must
We should close the channel of `stream1` when `updateSub` is called, making `stream1` and `stream2` 2 separate references.

2. Maybe
Forbid the reuse of the same subscription id for different subscriptions and remove `updateSub`.

In this case, the caller of this API should do
```js
const stream1 = await pool.newSub("profileStream 1", {...});
const stream2 = await pool.updateSub("profileStream 2", {...});
```
Use a suffix index to indicate that it's from the same feature but for different iterations.
Author Public Key
npub1mc9ykrmrpwk3k2x23s9yanqa2gws47reqy342xf39d80sf83x97sjhhm00