mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-08 16:28:49 +00:00
Merge pull request #214 from Egge7/messagequeue
Replace array list queue with a linked list one
This commit is contained in:
9
relay.ts
9
relay.ts
@@ -3,6 +3,7 @@
|
|||||||
import {verifySignature, validateEvent, type Event} from './event.ts'
|
import {verifySignature, validateEvent, type Event} from './event.ts'
|
||||||
import {matchFilters, type Filter} from './filter.ts'
|
import {matchFilters, type Filter} from './filter.ts'
|
||||||
import {getHex64, getSubscriptionId} from './fakejson.ts'
|
import {getHex64, getSubscriptionId} from './fakejson.ts'
|
||||||
|
import { MessageQueue } from './utils.ts'
|
||||||
|
|
||||||
type RelayEvent = {
|
type RelayEvent = {
|
||||||
connect: () => void | Promise<void>
|
connect: () => void | Promise<void>
|
||||||
@@ -122,24 +123,24 @@ export function relayInit(
|
|||||||
listeners.disconnect.forEach(cb => cb())
|
listeners.disconnect.forEach(cb => cb())
|
||||||
}
|
}
|
||||||
|
|
||||||
let incomingMessageQueue: string[] = []
|
let incomingMessageQueue: MessageQueue = new MessageQueue()
|
||||||
let handleNextInterval: any
|
let handleNextInterval: any
|
||||||
|
|
||||||
ws.onmessage = e => {
|
ws.onmessage = e => {
|
||||||
incomingMessageQueue.push(e.data)
|
incomingMessageQueue.enqueue(e.data)
|
||||||
if (!handleNextInterval) {
|
if (!handleNextInterval) {
|
||||||
handleNextInterval = setInterval(handleNext, 0)
|
handleNextInterval = setInterval(handleNext, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNext() {
|
function handleNext() {
|
||||||
if (incomingMessageQueue.length === 0) {
|
if (incomingMessageQueue.size === 0) {
|
||||||
clearInterval(handleNextInterval)
|
clearInterval(handleNextInterval)
|
||||||
handleNextInterval = null
|
handleNextInterval = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var json = incomingMessageQueue.shift()
|
var json = incomingMessageQueue.dequeue()
|
||||||
if (!json) return
|
if (!json) return
|
||||||
|
|
||||||
let subid = getSubscriptionId(json)
|
let subid = getSubscriptionId(json)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {buildEvent} from './test-helpers.ts'
|
import {buildEvent} from './test-helpers.ts'
|
||||||
import {
|
import {
|
||||||
|
MessageQueue,
|
||||||
insertEventIntoAscendingList,
|
insertEventIntoAscendingList,
|
||||||
insertEventIntoDescendingList,
|
insertEventIntoDescendingList,
|
||||||
} from './utils.ts'
|
} from './utils.ts'
|
||||||
@@ -191,3 +192,48 @@ describe('inserting into a asc sorted list of events', () => {
|
|||||||
expect(list1).toHaveLength(3)
|
expect(list1).toHaveLength(3)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('enque a message into MessageQueue', () => {
|
||||||
|
test('enque into an empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
expect(queue.first!.value).toBe('node1')
|
||||||
|
})
|
||||||
|
test('enque into a non-empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
queue.enqueue('node3')
|
||||||
|
queue.enqueue('node2')
|
||||||
|
expect(queue.first!.value).toBe('node1')
|
||||||
|
expect(queue.last!.value).toBe('node2')
|
||||||
|
expect(queue.size).toBe(3)
|
||||||
|
})
|
||||||
|
test('dequeue from an empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
const item1 = queue.dequeue()
|
||||||
|
expect(item1).toBe(null)
|
||||||
|
expect(queue.size).toBe(0)
|
||||||
|
})
|
||||||
|
test('dequeue from a non-empty queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
queue.enqueue('node3')
|
||||||
|
queue.enqueue('node2')
|
||||||
|
const item1 = queue.dequeue()
|
||||||
|
expect(item1).toBe('node1')
|
||||||
|
const item2 = queue.dequeue()
|
||||||
|
expect(item2).toBe('node3')
|
||||||
|
})
|
||||||
|
test('dequeue more than in queue', () => {
|
||||||
|
const queue = new MessageQueue()
|
||||||
|
queue.enqueue('node1')
|
||||||
|
queue.enqueue('node3')
|
||||||
|
const item1 = queue.dequeue()
|
||||||
|
expect(item1).toBe('node1')
|
||||||
|
const item2 = queue.dequeue()
|
||||||
|
expect(item2).toBe('node3')
|
||||||
|
expect(queue.size).toBe(0)
|
||||||
|
const item3 = queue.dequeue()
|
||||||
|
expect(item3).toBe(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
76
utils.ts
76
utils.ts
@@ -109,3 +109,79 @@ export function insertEventIntoAscendingList(
|
|||||||
|
|
||||||
return sortedArray
|
return sortedArray
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class MessageNode {
|
||||||
|
private _value: string
|
||||||
|
private _next: MessageNode | null
|
||||||
|
|
||||||
|
public get value(): string {
|
||||||
|
return this._value
|
||||||
|
}
|
||||||
|
public set value(message: string) {
|
||||||
|
this._value = message
|
||||||
|
}
|
||||||
|
public get next(): MessageNode | null {
|
||||||
|
return this._next
|
||||||
|
}
|
||||||
|
public set next(node: MessageNode | null) {
|
||||||
|
this._next = node
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(message: string) {
|
||||||
|
this._value = message
|
||||||
|
this._next = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MessageQueue {
|
||||||
|
private _first: MessageNode | null
|
||||||
|
private _last: MessageNode | null
|
||||||
|
|
||||||
|
public get first(): MessageNode | null {
|
||||||
|
return this._first
|
||||||
|
}
|
||||||
|
public set first(messageNode: MessageNode | null) {
|
||||||
|
this._first = messageNode
|
||||||
|
}
|
||||||
|
public get last(): MessageNode | null {
|
||||||
|
return this._last
|
||||||
|
}
|
||||||
|
public set last(messageNode: MessageNode | null) {
|
||||||
|
this._last = messageNode
|
||||||
|
}
|
||||||
|
private _size: number
|
||||||
|
public get size(): number {
|
||||||
|
return this._size
|
||||||
|
}
|
||||||
|
public set size(v: number) {
|
||||||
|
this._size = v
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._first = null
|
||||||
|
this._last = null
|
||||||
|
this._size = 0
|
||||||
|
}
|
||||||
|
enqueue(message: string): boolean {
|
||||||
|
const newNode = new MessageNode(message)
|
||||||
|
if (this._size === 0 || !this._last) {
|
||||||
|
this._first = newNode
|
||||||
|
this._last = newNode
|
||||||
|
} else {
|
||||||
|
this._last.next = newNode
|
||||||
|
this._last = newNode
|
||||||
|
}
|
||||||
|
this._size++
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
dequeue(): string | null {
|
||||||
|
if (this._size === 0 || !this._first) return null
|
||||||
|
|
||||||
|
let prev = this._first
|
||||||
|
this._first = prev.next
|
||||||
|
prev.next = null
|
||||||
|
|
||||||
|
this._size--
|
||||||
|
return prev.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user