Skip to content

Commit

Permalink
fix(node/cluster): improve stubs to make log4js work (#25146)
Browse files Browse the repository at this point in the history
- Add missing exports to `node:cluster`
- Fix default export not being an instance of `EventEmitter`
- Fix aliasing of properties
- Fix `disconnected` -> `disconnect` export naming

This makes `log4js` work in Deno. `karma` starts too, but somehow the
server isn't responding. That looks like a different issue.

Fixes #24858
  • Loading branch information
marvinhagemeister authored and lucacasonato committed Aug 29, 2024
1 parent 7eaa395 commit 4cb7acb
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 24 deletions.
71 changes: 47 additions & 24 deletions ext/node/polyfills/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright Joyent and Node contributors. All rights reserved. MIT license.

import { notImplemented } from "ext:deno_node/_utils.ts";
import { EventEmitter } from "node:events";

/** A Worker object contains all public information and method about a worker.
* In the primary it can be obtained using cluster.workers. In a worker it can
Expand All @@ -13,20 +14,23 @@ export class Worker {
}
}
/** Calls .disconnect() on each worker in cluster.workers. */
export function disconnected() {
notImplemented("cluster.disconnected");
export function disconnect() {
notImplemented("cluster.disconnect");
}
/** Spawn a new worker process. */
export function fork() {
// deno-lint-ignore no-explicit-any
export function fork(_env?: any): Worker {
notImplemented("cluster.fork");
}
/** True if the process is a primary. This is determined by
* the process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is undefined,
* then isPrimary is true. */
export const isPrimary = undefined;
// TODO(@marvinhagemeister): Replace this with an env check once
// we properly set NODE_UNIQUE_ID
export const isPrimary = true;
/** True if the process is not a primary (it is the negation of
* cluster.isPrimary). */
export const isWorker = undefined;
export const isWorker = false;
/** Deprecated alias for cluster.isPrimary. details. */
export const isMaster = isPrimary;
/** The scheduling policy, either cluster.SCHED_RR for round-robin or
Expand All @@ -35,35 +39,54 @@ export const isMaster = isPrimary;
* .setupPrimary() is called, whichever comes first. */
export const schedulingPolicy = undefined;
/** The settings object */
export const settings = undefined;
/** Deprecated alias for .setupPrimary(). */
export function setupMaster() {
notImplemented("cluster.setupMaster");
}
export const settings = {};
/** setupPrimary is used to change the default 'fork' behavior. Once called,
* the settings will be present in cluster.settings. */
export function setupPrimary() {
notImplemented("cluster.setupPrimary");
}
/** Deprecated alias for .setupPrimary(). */
export const setupMaster = setupPrimary;
/** A reference to the current worker object. Not available in the primary
* process. */
export const worker = undefined;
/** A hash that stores the active worker objects, keyed by id field. Makes it
* easy to loop through all the workers. It is only available in the primary
* process. */
export const workers = undefined;
export const workers = {};

export default {
Worker,
disconnected,
fork,
isPrimary,
isWorker,
isMaster,
schedulingPolicy,
settings,
setupMaster,
setupPrimary,
worker,
workers,
export const SCHED_NONE = 1;
export const SCHED_RR = 2;

const cluster = new EventEmitter() as EventEmitter & {
isWorker: boolean;
isMaster: boolean;
isPrimary: boolean;
Worker: Worker;
workers: Record<string, Worker>;
settings: Record<string, unknown>;
// deno-lint-ignore no-explicit-any
setupPrimary(options?: any): void;
// deno-lint-ignore no-explicit-any
setupMaster(options?: any): void;
// deno-lint-ignore no-explicit-any
fork(env: any): Worker;
// deno-lint-ignore no-explicit-any
disconnect(cb: any): void;
SCHED_NONE: 1;
SCHED_RR: 2;
};
cluster.isWorker = isWorker;
cluster.isMaster = isMaster;
cluster.isPrimary = isPrimary;
cluster.Worker = Worker;
cluster.workers = workers;
cluster.settings = {};
cluster.setupPrimary = setupPrimary;
cluster.setupMaster = setupMaster;
cluster.fork = fork;
cluster.disconnect = disconnect;
cluster.SCHED_NONE = SCHED_NONE;
cluster.SCHED_RR = SCHED_RR;

export default cluster;
1 change: 1 addition & 0 deletions tests/integration/node_unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ util::unit_test_factory!(
assertion_error_test,
buffer_test,
child_process_test,
cluster_test,
console_test,
crypto_cipher_gcm_test = crypto / crypto_cipher_gcm_test,
crypto_cipher_test = crypto / crypto_cipher_test,
Expand Down
43 changes: 43 additions & 0 deletions tests/unit_node/cluster_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assertEquals } from "@std/assert";
import cluster from "node:cluster";
import * as clusterNamed from "node:cluster";

Deno.test("[node/cluster] has all node exports", () => {
assertEquals(cluster.isPrimary, true);
assertEquals(cluster.isMaster, true);
assertEquals(cluster.isWorker, false);
assertEquals(typeof cluster.disconnect, "function");
assertEquals(typeof cluster.on, "function");
assertEquals(cluster.workers, {});
assertEquals(cluster.settings, {});
assertEquals(cluster.SCHED_NONE, 1);
assertEquals(cluster.SCHED_RR, 2);
assertEquals(typeof cluster.fork, "function");
assertEquals(typeof cluster.disconnect, "function");
assertEquals(typeof cluster.setupPrimary, "function");
assertEquals(cluster.setupPrimary, cluster.setupMaster);

// @ts-ignore Our @types/node version is too old
assertEquals(cluster.setupPrimary, clusterNamed.setupPrimary);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.setupMaster, clusterNamed.setupMaster);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.workers, clusterNamed.workers);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.settings, clusterNamed.settings);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.fork, clusterNamed.fork);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.disconnect, clusterNamed.disconnect);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.SCHED_NONE, clusterNamed.SCHED_NONE);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.SCHED_RR, clusterNamed.SCHED_RR);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.isWorker, clusterNamed.isWorker);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.isPrimary, clusterNamed.isPrimary);
// @ts-ignore Our @types/node version is too old
assertEquals(cluster.isMaster, clusterNamed.isMaster);
});

0 comments on commit 4cb7acb

Please sign in to comment.