Skip to content

Commit

Permalink
refactor: make event-loop-yielder more concise
Browse files Browse the repository at this point in the history
  • Loading branch information
lierdakil authored and aminya committed Mar 18, 2021
1 parent 89a5933 commit 6ef490f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 29 deletions.
6 changes: 3 additions & 3 deletions src/highlighter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TextBuffer, LanguageMode } from "atom"
import { EventLoopYielder, maxTimeError } from "./utils/event-loop-yielder"
import { eventLoopYielder, maxTimeError } from "./utils/event-loop-yielder"

declare module "atom" {
interface GrammarRegistry {
Expand All @@ -25,7 +25,7 @@ declare module "atom" {
}

export async function highlightTreeSitter(sourceCode: string, scopeName: string) {
const eventLoopYielder = new EventLoopYielder(100, 5000)
const yielder = eventLoopYielder(100, 5000)
const buf = new TextBuffer()
try {
const grammar = atom.grammars.grammarForId(scopeName)
Expand All @@ -49,7 +49,7 @@ export async function highlightTreeSitter(sourceCode: string, scopeName: string)
const nextPos = iter.getPosition()
res.push(escapeHTML(buf.getTextInRange([pos, nextPos])))

if (!(await eventLoopYielder.yield())) {
if (!(await yielder())) {
console.error(maxTimeError("Atom-IDE-Markdown-Service: Highlighter", 5))
break
}
Expand Down
39 changes: 13 additions & 26 deletions src/utils/event-loop-yielder.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,21 @@
/**
* A class to allow the JavaScript event loop continue for a given interval between each iteration of a CPU intensive loop
* If the time spent in the loop reaches the given maxTime, the operation is killed
* A helper to allow the JavaScript event loop continue for a given interval between each
* iteration of a CPU intensive loop. If the time spent in the loop reaches the given
* maxTime, the operation is killed.
*
* @returns An async function to call inside your heavy loop. It will return `false` if
* the operation has exceeded the given max time (`true` otherwise).
*/
export class EventLoopYielder {
private delayMs: number
private maxTimeMs: number
private started: number
private lastYield: number

constructor(delayMs: number, maxTimeMs: number) {
this.delayMs = delayMs
this.maxTimeMs = maxTimeMs
this.started = performance.now()
this.lastYield = this.started
}

/**
* Call yield method inside your heavy loop
* @returns it will be `false` if the operation has exceeded the given max time (`true` otherwise).
*/
public async yield(): Promise<boolean> {
export function eventLoopYielder(delayMs: number, maxTimeMs: number) {
const started = performance.now()
let lastYield = started
return async function (): Promise<boolean> {
const now = performance.now()
if (now - this.lastYield > this.delayMs) {
if (now - lastYield > delayMs) {
await new Promise(setImmediate)
this.lastYield = now
}
if (now - this.started > this.maxTimeMs) {
return false
lastYield = now
}
return true
return now - started <= maxTimeMs
}
}

Expand Down

0 comments on commit 6ef490f

Please sign in to comment.