Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): remove parcel/watcher #19751

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/nx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
},
"homepage": "https://nx.dev",
"dependencies": {
"@parcel/watcher": "2.0.4",
"@yarnpkg/lockfile": "^1.1.0",
"@yarnpkg/parsers": "3.0.0-rc.46",
"@zkochan/js-yaml": "0.0.6",
Expand Down
6 changes: 0 additions & 6 deletions packages/nx/src/daemon/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,6 @@ export class DaemonClient {
this._out = await open(DAEMON_OUTPUT_LOG_FILE, 'a');
this._err = await open(DAEMON_OUTPUT_LOG_FILE, 'a');

if (this.nxJson.tasksRunnerOptions?.default?.options?.useParcelWatcher) {
DAEMON_ENV_SETTINGS['NX_NATIVE_WATCHER'] = 'false';
} else {
DAEMON_ENV_SETTINGS['NX_NATIVE_WATCHER'] = 'true';
}

const backgroundProcess = spawn(
process.execPath,
[join(__dirname, '../server/start.js')],
Expand Down
15 changes: 11 additions & 4 deletions packages/nx/src/daemon/server/outputs-tracking.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EventType } from '../../native';
import {
_outputsHashesMatch,
_recordOutputsHash,
Expand All @@ -19,7 +20,7 @@ describe('outputs tracking', () => {
it('should invalidate output when it is exact match', () => {
_recordOutputsHash(['dist/app/app1'], '123');
processFileChangesInOutputs(
[{ path: 'dist/app/app1', type: 'update' }],
[{ path: 'dist/app/app1', type: EventType.update }],
now
);
expect(recordedHash('dist/app/app1')).toBeUndefined();
Expand All @@ -28,21 +29,27 @@ describe('outputs tracking', () => {
it('should invalidate output when it is a child', () => {
_recordOutputsHash(['dist/app/app1'], '123');
processFileChangesInOutputs(
[{ path: 'dist/app/app1/child', type: 'update' }],
[{ path: 'dist/app/app1/child', type: EventType.update }],
now
);
expect(recordedHash('dist/app/app1')).toBeUndefined();
});

it('should invalidate output when it is a parent', () => {
_recordOutputsHash(['dist/app/app1'], '123');
processFileChangesInOutputs([{ path: 'dist/app', type: 'update' }], now);
processFileChangesInOutputs(
[{ path: 'dist/app', type: EventType.update }],
now
);
expect(recordedHash('dist/app/app1')).toBeUndefined();
});

it('should not invalidate anything when no match', () => {
_recordOutputsHash(['dist/app/app1'], '123');
processFileChangesInOutputs([{ path: 'dist/app2', type: 'update' }], now);
processFileChangesInOutputs(
[{ path: 'dist/app2', type: EventType.update }],
now
);
expect(recordedHash('dist/app/app1')).toEqual('123');
});
});
10 changes: 4 additions & 6 deletions packages/nx/src/daemon/server/outputs-tracking.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { lstat } from 'fs-extra';
import { dirname, join } from 'path';
import { workspaceRoot } from '../../utils/workspace-root';
import { dirname } from 'path';
import { WatchEvent, getFilesForOutputs } from '../../native';
import { collapseExpandedOutputs } from '../../utils/collapse-expanded-outputs';
import type { Event } from '@parcel/watcher';
import { getFilesForOutputs } from '../../native';
import { workspaceRoot } from '../../utils/workspace-root';

let disabled = false;

Expand Down Expand Up @@ -66,7 +64,7 @@ async function normalizeOutputs(outputs: string[]) {
}

export function processFileChangesInOutputs(
changeEvents: Event[],
changeEvents: WatchEvent[],
now: number = undefined
) {
if (!now) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,37 +140,10 @@ function computeWorkspaceConfigHash(
return hashArray(projectConfigurationStrings);
}

/**
* Temporary work around to handle nested gitignores. The parcel file watcher doesn't handle them well,
* so we need to filter them out here.
*
* TODO(Cammisuli): remove after 16.4 - Rust watcher handles nested gitignores
*/
function filterUpdatedFiles(files: string[]) {
if (files.length === 0 || process.env.NX_NATIVE_WATCHER === 'true') {
return files;
}

try {
const quoted = files.map((f) => '"' + f + '"');
const ignored = execSync(`git check-ignore ${quoted.join(' ')}`, {
windowsHide: true,
})
.toString()
.split('\n');
return files.filter((f) => ignored.indexOf(f) === -1);
} catch (e) {
// none of the files were ignored
return files;
}
}

async function processCollectedUpdatedAndDeletedFiles() {
try {
performance.mark('hash-watched-changes-start');
const updatedFiles = filterUpdatedFiles([
...collectedUpdatedFiles.values(),
]);
const updatedFiles = [...collectedUpdatedFiles.values()];
const deletedFiles = [...collectedDeletedFiles.values()];
let updatedFileHashes = updateFilesInContext(updatedFiles, deletedFiles);
performance.mark('hash-watched-changes-end');
Expand Down
139 changes: 41 additions & 98 deletions packages/nx/src/daemon/server/server.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,57 @@
import { workspaceRoot } from '../../utils/workspace-root';
import { existsSync, statSync } from 'fs';
import { createServer, Server, Socket } from 'net';
import { join } from 'path';
import { PerformanceObserver } from 'perf_hooks';
import { hashArray } from '../../hasher/file-hasher';
import { hashFile } from '../../native';
import { consumeMessagesFromSocket } from '../../utils/consume-messages-from-socket';
import { readJsonFile } from '../../utils/fileutils';
import { PackageJson } from '../../utils/package-json';
import { nxVersion } from '../../utils/versions';
import { setupWorkspaceContext } from '../../utils/workspace-context';
import { workspaceRoot } from '../../utils/workspace-root';
import { writeDaemonJsonProcessCache } from '../cache';
import {
FULL_OS_SOCKET_PATH,
isWindows,
killSocketOrPath,
} from '../socket-utils';
import {
registeredFileWatcherSockets,
removeRegisteredFileWatcherSocket,
} from './file-watching/file-watcher-sockets';
import { handleHashTasks } from './handle-hash-tasks';
import {
handleOutputsHashesMatch,
handleRecordOutputsHash,
} from './handle-outputs-tracking';
import { handleProcessInBackground } from './handle-process-in-background';
import { handleRequestFileData } from './handle-request-file-data';
import { handleRequestProjectGraph } from './handle-request-project-graph';
import { handleRequestShutdown } from './handle-request-shutdown';
import { serverLogger } from './logger';
import {
getOutputsWatcherSubscription,
disableOutputsTracking,
processFileChangesInOutputs,
} from './outputs-tracking';
import { addUpdatedAndDeletedFiles } from './project-graph-incremental-recomputation';
import {
getOutputWatcherInstance,
getSourceWatcherSubscription,
getWatcherInstance,
handleServerProcessTermination,
resetInactivityTimeout,
respondToClient,
respondWithErrorAndExit,
SERVER_INACTIVITY_TIMEOUT_MS,
storeOutputsWatcherSubscription,
storeOutputWatcherInstance,
storeProcessJsonSubscription,
storeSourceWatcherSubscription,
storeWatcherInstance,
} from './shutdown-utils';
import {
convertChangeEventsToLogMessage,
subscribeToOutputsChanges,
subscribeToWorkspaceChanges,
FileWatcherCallback,
subscribeToServerProcessJsonChanges,
watchWorkspace,
watchOutputFiles,
watchWorkspace,
} from './watcher';
import { addUpdatedAndDeletedFiles } from './project-graph-incremental-recomputation';
import { existsSync, statSync } from 'fs';
import { handleRequestProjectGraph } from './handle-request-project-graph';
import { handleProcessInBackground } from './handle-process-in-background';
import {
handleOutputsHashesMatch,
handleRecordOutputsHash,
} from './handle-outputs-tracking';
import { consumeMessagesFromSocket } from '../../utils/consume-messages-from-socket';
import {
disableOutputsTracking,
processFileChangesInOutputs,
} from './outputs-tracking';
import { handleRequestShutdown } from './handle-request-shutdown';
import {
registeredFileWatcherSockets,
removeRegisteredFileWatcherSocket,
} from './file-watching/file-watcher-sockets';
import { nxVersion } from '../../utils/versions';
import { readJsonFile } from '../../utils/fileutils';
import { PackageJson } from '../../utils/package-json';
import { getDaemonProcessIdSync, writeDaemonJsonProcessCache } from '../cache';
import { handleHashTasks } from './handle-hash-tasks';
import { hashArray } from '../../hasher/file-hasher';
import { handleRequestFileData } from './handle-request-file-data';
import { setupWorkspaceContext } from '../../utils/workspace-context';
import { hashFile } from '../../native';

let performanceObserver: PerformanceObserver | undefined;
let workspaceWatcherError: Error | undefined;
Expand Down Expand Up @@ -109,7 +101,6 @@ const server = createServer(async (socket) => {
});
});
registerProcessTerminationListeners();
registerProcessServerJsonTracking();

async function handleMessage(socket, data: string) {
if (workspaceWatcherError) {
Expand Down Expand Up @@ -239,23 +230,6 @@ function registerProcessTerminationListeners() {
);
}

async function registerProcessServerJsonTracking() {
if (useNativeWatcher()) {
return;
}

storeProcessJsonSubscription(
await subscribeToServerProcessJsonChanges(async () => {
if (getDaemonProcessIdSync() !== process.pid) {
await handleServerProcessTermination({
server,
reason: 'this process is no longer the current daemon',
});
}
})
);
}

let existingLockHash: string | undefined;

function daemonIsOutdated(): boolean {
Expand Down Expand Up @@ -419,46 +393,20 @@ export async function startServer(): Promise<Server> {
// this triggers the storage of the lock file hash
daemonIsOutdated();

if (useNativeWatcher()) {
if (!getWatcherInstance()) {
storeWatcherInstance(
await watchWorkspace(server, handleWorkspaceChanges)
);
if (!getWatcherInstance()) {
storeWatcherInstance(
await watchWorkspace(server, handleWorkspaceChanges)
);

serverLogger.watcherLog(
`Subscribed to changes within: ${workspaceRoot} (native)`
);
}

if (!getOutputWatcherInstance()) {
storeOutputWatcherInstance(
await watchOutputFiles(handleOutputsChanges)
);
}
} else {
if (!getSourceWatcherSubscription()) {
storeSourceWatcherSubscription(
await subscribeToWorkspaceChanges(
server,
handleWorkspaceChanges
)
);
serverLogger.watcherLog(
`Subscribed to changes within: ${workspaceRoot}`
);
}
serverLogger.watcherLog(
`Subscribed to changes within: ${workspaceRoot} (native)`
);
}

// temporary disable outputs tracking on linux
const outputsTrackingIsEnabled = process.platform != 'linux';
if (outputsTrackingIsEnabled) {
if (!getOutputsWatcherSubscription()) {
storeOutputsWatcherSubscription(
await subscribeToOutputsChanges(handleOutputsChanges)
);
}
} else {
disableOutputsTracking();
}
if (!getOutputWatcherInstance()) {
storeOutputWatcherInstance(
await watchOutputFiles(handleOutputsChanges)
);
}

return resolve(server);
Expand All @@ -471,8 +419,3 @@ export async function startServer(): Promise<Server> {
}
});
}

// TODO(cammisuli): remove with nx 16.6 (only our watcher will be supported)
function useNativeWatcher() {
return process.env.NX_NATIVE_WATCHER === 'true';
}
44 changes: 0 additions & 44 deletions packages/nx/src/daemon/server/shutdown-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,11 @@ import { workspaceRoot } from '../../utils/workspace-root';
import type { Server, Socket } from 'net';
import { serverLogger } from './logger';
import { serializeResult } from '../socket-utils';
import type { AsyncSubscription } from '@parcel/watcher';
import { deleteDaemonJsonProcessCache } from '../cache';
import type { Watcher } from '../../native';

export const SERVER_INACTIVITY_TIMEOUT_MS = 10800000 as const; // 10800000 ms = 3 hours

let sourceWatcherSubscription: AsyncSubscription | undefined;
let outputsWatcherSubscription: AsyncSubscription | undefined;

export function getSourceWatcherSubscription() {
return sourceWatcherSubscription;
}

export function storeSourceWatcherSubscription(s: AsyncSubscription) {
sourceWatcherSubscription = s;
}

export function getOutputsWatcherSubscription() {
return outputsWatcherSubscription;
}

export function storeOutputsWatcherSubscription(s: AsyncSubscription) {
outputsWatcherSubscription = s;
}

let processJsonSubscription: AsyncSubscription | undefined;

export function storeProcessJsonSubscription(s: AsyncSubscription) {
processJsonSubscription = s;
}

let watcherInstance: Watcher | undefined;
export function storeWatcherInstance(instance: Watcher) {
watcherInstance = instance;
Expand Down Expand Up @@ -61,24 +35,6 @@ export async function handleServerProcessTermination({
try {
server.close();
deleteDaemonJsonProcessCache();
if (sourceWatcherSubscription) {
await sourceWatcherSubscription.unsubscribe();
serverLogger.watcherLog(
`Unsubscribed from changes within: ${workspaceRoot} (sources)`
);
}
if (outputsWatcherSubscription) {
await outputsWatcherSubscription.unsubscribe();
serverLogger.watcherLog(
`Unsubscribed from changes within: ${workspaceRoot} (outputs)`
);
}
if (processJsonSubscription) {
await processJsonSubscription.unsubscribe();
serverLogger.watcherLog(
`Unsubscribed from changes within: ${workspaceRoot} (server-process.json)`
);
}

if (watcherInstance) {
await watcherInstance.stop();
Expand Down
Loading