mirror of
https://github.com/immich-app/immich.git
synced 2024-12-29 15:11:58 +00:00
chore: remove watcher polling option (#7480)
* remove watcher polling * fix lint * add db migration
This commit is contained in:
parent
784d92dbb3
commit
e4f32a045d
14 changed files with 15 additions and 74 deletions
|
@ -88,10 +88,7 @@ Some basic examples:
|
||||||
|
|
||||||
This feature - currently hidden in the config file - is considered experimental and for advanced users only. If enabled, it will allow automatic watching of the filesystem which means new assets are automatically imported to Immich without needing to rescan. Deleted assets are, as always, marked as offline and can be removed with the "Remove offline files" button.
|
This feature - currently hidden in the config file - is considered experimental and for advanced users only. If enabled, it will allow automatic watching of the filesystem which means new assets are automatically imported to Immich without needing to rescan. Deleted assets are, as always, marked as offline and can be removed with the "Remove offline files" button.
|
||||||
|
|
||||||
If your photos are on a network drive you will likely have to enable filesystem polling. The performance hit for polling large libraries is currently unknown, feel free to test this feature and report back. In addition to the boolean feature flag, the configuration file allows customization of the following parameters, please see the [chokidar documentation](https://github.com/paulmillr/chokidar?tab=readme-ov-file#performance) for reference.
|
If your photos are on a network drive, automatic file watching likely won't work. In that case, you will have to rely on a periodic library refresh to pull in your changes.
|
||||||
|
|
||||||
- `usePolling` (default: `false`).
|
|
||||||
- `interval`. (default: 10000). When using polling, this is how often (in milliseconds) the filesystem is polled.
|
|
||||||
|
|
||||||
### Nightly job
|
### Nightly job
|
||||||
|
|
||||||
|
|
BIN
mobile/openapi/doc/SystemConfigLibraryWatchDto.md
generated
BIN
mobile/openapi/doc/SystemConfigLibraryWatchDto.md
generated
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -9831,18 +9831,10 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
|
||||||
"interval": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"usePolling": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"enabled",
|
"enabled"
|
||||||
"interval",
|
|
||||||
"usePolling"
|
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
|
12
open-api/typescript-sdk/axios-client/api.ts
generated
12
open-api/typescript-sdk/axios-client/api.ts
generated
|
@ -4401,18 +4401,6 @@ export interface SystemConfigLibraryWatchDto {
|
||||||
* @memberof SystemConfigLibraryWatchDto
|
* @memberof SystemConfigLibraryWatchDto
|
||||||
*/
|
*/
|
||||||
'enabled': boolean;
|
'enabled': boolean;
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof SystemConfigLibraryWatchDto
|
|
||||||
*/
|
|
||||||
'interval': number;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof SystemConfigLibraryWatchDto
|
|
||||||
*/
|
|
||||||
'usePolling': boolean;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
BIN
open-api/typescript-sdk/fetch-client.ts
generated
BIN
open-api/typescript-sdk/fetch-client.ts
generated
Binary file not shown.
|
@ -112,20 +112,13 @@ export class LibraryService extends EventEmitter {
|
||||||
ignore: library.exclusionPatterns,
|
ignore: library.exclusionPatterns,
|
||||||
});
|
});
|
||||||
|
|
||||||
const config = await this.configCore.getConfig();
|
|
||||||
const { usePolling, interval } = config.library.watch;
|
|
||||||
|
|
||||||
this.logger.debug(`Settings for watcher: usePolling: ${usePolling}, interval: ${interval}`);
|
|
||||||
|
|
||||||
let _resolve: () => void;
|
let _resolve: () => void;
|
||||||
const ready$ = new Promise<void>((resolve) => (_resolve = resolve));
|
const ready$ = new Promise<void>((resolve) => (_resolve = resolve));
|
||||||
|
|
||||||
this.watchers[id] = this.storageRepository.watch(
|
this.watchers[id] = this.storageRepository.watch(
|
||||||
library.importPaths,
|
library.importPaths,
|
||||||
{
|
{
|
||||||
usePolling,
|
usePolling: false,
|
||||||
interval,
|
|
||||||
binaryInterval: interval,
|
|
||||||
ignoreInitial: true,
|
ignoreInitial: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
import { validateCronExpression } from '@app/domain';
|
import { validateCronExpression } from '@app/domain';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import {
|
import {
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsInt,
|
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsObject,
|
IsObject,
|
||||||
IsPositive,
|
|
||||||
IsString,
|
IsString,
|
||||||
Validate,
|
Validate,
|
||||||
ValidateIf,
|
ValidateIf,
|
||||||
|
@ -38,14 +35,6 @@ export class SystemConfigLibraryScanDto {
|
||||||
export class SystemConfigLibraryWatchDto {
|
export class SystemConfigLibraryWatchDto {
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
enabled!: boolean;
|
enabled!: boolean;
|
||||||
|
|
||||||
@IsBoolean()
|
|
||||||
usePolling!: boolean;
|
|
||||||
|
|
||||||
@IsInt()
|
|
||||||
@IsPositive()
|
|
||||||
@ApiProperty({ type: 'integer' })
|
|
||||||
interval!: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SystemConfigLibraryDto {
|
export class SystemConfigLibraryDto {
|
||||||
|
|
|
@ -132,8 +132,6 @@ export const defaults = Object.freeze<SystemConfig>({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
usePolling: false,
|
|
||||||
interval: 10_000,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
|
|
|
@ -136,8 +136,6 @@ const updatedConfig = Object.freeze<SystemConfig>({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
usePolling: false,
|
|
||||||
interval: 10_000,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -51,8 +51,6 @@ export enum SystemConfigKey {
|
||||||
LIBRARY_SCAN_CRON_EXPRESSION = 'library.scan.cronExpression',
|
LIBRARY_SCAN_CRON_EXPRESSION = 'library.scan.cronExpression',
|
||||||
|
|
||||||
LIBRARY_WATCH_ENABLED = 'library.watch.enabled',
|
LIBRARY_WATCH_ENABLED = 'library.watch.enabled',
|
||||||
LIBRARY_WATCH_USE_POLLING = 'library.watch.usePolling',
|
|
||||||
LIBRARY_WATCH_INTERVAL = 'library.watch.interval',
|
|
||||||
|
|
||||||
LOGGING_ENABLED = 'logging.enabled',
|
LOGGING_ENABLED = 'logging.enabled',
|
||||||
LOGGING_LEVEL = 'logging.level',
|
LOGGING_LEVEL = 'logging.level',
|
||||||
|
@ -268,8 +266,6 @@ export interface SystemConfig {
|
||||||
};
|
};
|
||||||
watch: {
|
watch: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
usePolling: boolean;
|
|
||||||
interval: number;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
server: {
|
server: {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class RemoveLibraryWatchPollingOption1709150004123 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DELETE FROM "system_config" WHERE key = 'library.watch.usePolling'`);
|
||||||
|
await queryRunner.query(`DELETE FROM "system_config" WHERE key = 'library.watch.interval'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(): Promise<void> {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,28 +42,6 @@
|
||||||
subtitle="Watch external libraries for file changes"
|
subtitle="Watch external libraries for file changes"
|
||||||
bind:checked={config.library.watch.enabled}
|
bind:checked={config.library.watch.enabled}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SettingSwitch
|
|
||||||
title="Use filesystem polling (EXPERIMENTAL)"
|
|
||||||
disabled={disabled || !config.library.watch.enabled}
|
|
||||||
subtitle="Use polling instead of native filesystem watching. This is required for network shares but can be very resource intensive. Use with care!"
|
|
||||||
bind:checked={config.library.watch.usePolling}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SettingInputField
|
|
||||||
inputType={SettingInputFieldType.NUMBER}
|
|
||||||
required={config.library.watch.usePolling}
|
|
||||||
disabled={disabled || !config.library.watch.usePolling || !config.library.watch.enabled}
|
|
||||||
label="Polling interval"
|
|
||||||
bind:value={config.library.watch.interval}
|
|
||||||
isEdited={config.library.watch.interval !== savedConfig.library.watch.interval}
|
|
||||||
>
|
|
||||||
<svelte:fragment slot="desc">
|
|
||||||
<p class="text-sm dark:text-immich-dark-fg">
|
|
||||||
Interval of filesystem polling, in milliseconds. Lower values will result in higher CPU usage.
|
|
||||||
</p>
|
|
||||||
</svelte:fragment>
|
|
||||||
</SettingInputField>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
|
|
Loading…
Reference in a new issue