workerManager.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import * as monaco from 'monaco-editor'
  2. import type { LanguageServiceDefaults } from '../register'
  3. import type { LogWorker, ICreateData } from './logWorker'
  4. import { LOG_LANGUAGE_ID } from '../definitions'
  5. const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000 // 2min
  6. export class WorkerManager {
  7. private readonly _defaults: LanguageServiceDefaults
  8. private _worker: monaco.editor.MonacoWebWorker<LogWorker> | null = null
  9. private _client: Promise<LogWorker> | null
  10. private readonly _idleCheckInterval: number
  11. private _lastUsedTime: number
  12. constructor(defaults: LanguageServiceDefaults) {
  13. this._defaults = defaults
  14. this._worker = null
  15. this._client = null
  16. this._idleCheckInterval = window.setInterval(() => this._checkIfIdle(), 30 * 1000)
  17. this._lastUsedTime = 0
  18. }
  19. private _stopWorker(): void {
  20. if (this._worker) {
  21. this._worker.dispose()
  22. this._worker = null
  23. }
  24. this._client = null
  25. }
  26. dispose(): void {
  27. clearInterval(this._idleCheckInterval)
  28. this._stopWorker()
  29. }
  30. private _checkIfIdle(): void {
  31. if (!this._worker) {
  32. return
  33. }
  34. let timePassedSinceLastUsed = Date.now() - this._lastUsedTime
  35. if (timePassedSinceLastUsed > STOP_WHEN_IDLE_FOR) {
  36. this._stopWorker()
  37. }
  38. }
  39. private _getClient(): Promise<LogWorker> {
  40. this._lastUsedTime = Date.now()
  41. if (!this._client) {
  42. this._worker = monaco.createWebWorker<LogWorker>({
  43. // module that exports the create() method and returns a `LogWorker` instance
  44. moduleId: 'vs/language/log/logWorker',
  45. createWorker: () => {
  46. return new Worker(new URL('./log.worker?esm', import.meta.url), { type: 'module' })
  47. },
  48. label: LOG_LANGUAGE_ID,
  49. // passed in to the create() method
  50. createData: {
  51. languageId: LOG_LANGUAGE_ID,
  52. } satisfies ICreateData,
  53. })
  54. this._client = <Promise<LogWorker>>(<any>this._worker.getProxy())
  55. }
  56. return this._client
  57. }
  58. getLanguageServiceWorker(...resources: monaco.Uri[]): Promise<LogWorker> {
  59. let _client: LogWorker
  60. return this._getClient()
  61. .then((client) => {
  62. _client = client
  63. })
  64. .then((_) => {
  65. if (this._worker) {
  66. return this._worker.withSyncedResources(resources)
  67. }
  68. })
  69. .then((_) => _client)
  70. }
  71. }