Get rid of Worker, use TaskQueue instead
This commit is contained in:
+81
-78
@@ -1,5 +1,5 @@
|
||||
import {Writable, Readable, writable, derived, get} from "svelte/store"
|
||||
import {Deferred, Worker, dissoc, identity, uniq, defer, sleep, assoc} from "@welshman/lib"
|
||||
import {Deferred, TaskQueue, dissoc, identity, uniq, defer, sleep, assoc} from "@welshman/lib"
|
||||
import {stamp, own, hash} from "@welshman/signer"
|
||||
import {
|
||||
TrustedEvent,
|
||||
@@ -129,7 +129,7 @@ export const thunks = writable<Record<string, Thunk | MergedThunk>>({})
|
||||
export const publishThunk = (request: ThunkRequest) => {
|
||||
const thunk = makeThunk(request)
|
||||
|
||||
thunkWorker.push(thunk)
|
||||
thunkQueue.push(thunk)
|
||||
|
||||
repository.publish(thunk.event)
|
||||
|
||||
@@ -147,7 +147,7 @@ export const publishThunks = (requests: ThunkRequest[]) => {
|
||||
const mergedThunk = mergeThunks(newThunks)
|
||||
|
||||
for (const thunk of newThunks) {
|
||||
thunkWorker.push(thunk)
|
||||
thunkQueue.push(thunk)
|
||||
|
||||
repository.publish(thunk.event)
|
||||
|
||||
@@ -167,96 +167,99 @@ export const abortThunk = (thunk: Thunk) => {
|
||||
repository.removeEvent(thunk.event.id)
|
||||
}
|
||||
|
||||
export const thunkWorker = new Worker<Thunk>()
|
||||
export const thunkQueue = new TaskQueue<Thunk>({
|
||||
batchSize: 50,
|
||||
processItem: (thunk: Thunk) => {
|
||||
let event = thunk.event
|
||||
|
||||
thunkWorker.addGlobalHandler((thunk: Thunk) => {
|
||||
let event = thunk.event
|
||||
// Handle abort immediately if possible
|
||||
if (thunk.controller.signal.aborted) return
|
||||
|
||||
// Handle abort immediately if possible
|
||||
if (thunk.controller.signal.aborted) return
|
||||
// If we were given a wrapped event, make sure to publish the wrapper, not the rumor
|
||||
if (isUnwrappedEvent(event)) {
|
||||
event = event.wrap
|
||||
}
|
||||
|
||||
// If we were given a wrapped event, make sure to publish the wrapper, not the rumor
|
||||
if (isUnwrappedEvent(event)) {
|
||||
event = event.wrap
|
||||
}
|
||||
// Avoid making this function async so multiple publishes can run concurrently
|
||||
Promise.resolve().then(async () => {
|
||||
const fail = (message: string) => {
|
||||
const status: ThunkStatusByUrl = {}
|
||||
|
||||
// Avoid making this function async so multiple publishes can run concurrently
|
||||
Promise.resolve().then(async () => {
|
||||
const fail = (message: string) => {
|
||||
const status: ThunkStatusByUrl = {}
|
||||
for (const url of thunk.request.relays) {
|
||||
status[url] = {status: PublishStatus.Failure, message}
|
||||
}
|
||||
|
||||
for (const url of thunk.request.relays) {
|
||||
status[url] = {status: PublishStatus.Failure, message}
|
||||
thunk.status.set(status)
|
||||
}
|
||||
|
||||
thunk.status.set(status)
|
||||
}
|
||||
// If the event was already signed, leave it alone. Otherwise, sign it now. This is to
|
||||
// decrease apparent latency in the UI that results from waiting for remote signers
|
||||
if (!isSignedEvent(event)) {
|
||||
const signer = getSigner(getSession(event.pubkey))
|
||||
|
||||
// If the event was already signed, leave it alone. Otherwise, sign it now. This is to
|
||||
// decrease apparent latency in the UI that results from waiting for remote signers
|
||||
if (!isSignedEvent(event)) {
|
||||
const signer = getSigner(getSession(event.pubkey))
|
||||
if (!signer) {
|
||||
return fail(`No signer found for ${event.pubkey}`)
|
||||
}
|
||||
|
||||
if (!signer) {
|
||||
return fail(`No signer found for ${event.pubkey}`)
|
||||
try {
|
||||
event = await signer.sign(event)
|
||||
} catch (e: any) {
|
||||
return fail(String(e.error || e))
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
event = await signer.sign(event)
|
||||
} catch (e: any) {
|
||||
return fail(String(e.error || e))
|
||||
// We're guaranteed to have a signed event at this point
|
||||
const signedEvent = event as SignedEvent
|
||||
|
||||
// Wait if the thunk is to be delayed
|
||||
if (thunk.request.delay) {
|
||||
await sleep(thunk.request.delay)
|
||||
}
|
||||
}
|
||||
|
||||
// We're guaranteed to have a signed event at this point
|
||||
const signedEvent = event as SignedEvent
|
||||
// Skip publishing if aborted
|
||||
if (thunk.controller.signal.aborted) {
|
||||
return
|
||||
}
|
||||
|
||||
// Wait if the thunk is to be delayed
|
||||
if (thunk.request.delay) {
|
||||
await sleep(thunk.request.delay)
|
||||
}
|
||||
// Send it off
|
||||
const pub = new MultiPublish({
|
||||
event: signedEvent,
|
||||
relays: thunk.request.relays,
|
||||
context: thunk.request.context,
|
||||
})
|
||||
|
||||
// Skip publishing if aborted
|
||||
if (thunk.controller.signal.aborted) {
|
||||
return
|
||||
}
|
||||
// Copy the signature over since we had deferred it
|
||||
const savedEvent = repository.getEvent(signedEvent.id) as SignedEvent
|
||||
|
||||
// Send it off
|
||||
const pub = new MultiPublish({
|
||||
event: signedEvent,
|
||||
relays: thunk.request.relays,
|
||||
context: thunk.request.context,
|
||||
// The event may already be replaced or deleted
|
||||
if (savedEvent) {
|
||||
savedEvent.sig = signedEvent.sig
|
||||
}
|
||||
|
||||
pub.on(PublishEvent.Success, (id: string, message: string, url: string) => {
|
||||
tracker.track(id, url)
|
||||
thunk.status.update(assoc(url, {status: PublishStatus.Success, message}))
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Failure, (id: string, message: string, url: string) => {
|
||||
thunk.status.update(assoc(url, {status: PublishStatus.Failure, message}))
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Timeout, (url: string) => {
|
||||
thunk.status.update(
|
||||
assoc(url, {status: PublishStatus.Timeout, message: "Publish timed out"}),
|
||||
)
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Aborted, (url: string) => {
|
||||
thunk.status.update(
|
||||
assoc(url, {status: PublishStatus.Aborted, message: "Publish was aborted"}),
|
||||
)
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Complete, () => {
|
||||
thunk.result.resolve(get(thunk.status))
|
||||
})
|
||||
})
|
||||
|
||||
// Copy the signature over since we had deferred it
|
||||
const savedEvent = repository.getEvent(signedEvent.id) as SignedEvent
|
||||
|
||||
// The event may already be replaced or deleted
|
||||
if (savedEvent) {
|
||||
savedEvent.sig = signedEvent.sig
|
||||
}
|
||||
|
||||
pub.on(PublishEvent.Success, (id: string, message: string, url: string) => {
|
||||
tracker.track(id, url)
|
||||
thunk.status.update(assoc(url, {status: PublishStatus.Success, message}))
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Failure, (id: string, message: string, url: string) => {
|
||||
thunk.status.update(assoc(url, {status: PublishStatus.Failure, message}))
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Timeout, (url: string) => {
|
||||
thunk.status.update(assoc(url, {status: PublishStatus.Timeout, message: "Publish timed out"}))
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Aborted, (url: string) => {
|
||||
thunk.status.update(
|
||||
assoc(url, {status: PublishStatus.Aborted, message: "Publish was aborted"}),
|
||||
)
|
||||
})
|
||||
|
||||
pub.on(PublishEvent.Complete, () => {
|
||||
thunk.result.resolve(get(thunk.status))
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user