|
@@ -2638,10 +2638,7 @@ class PageService {
|
|
|
return isUnique;
|
|
return isUnique;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // TODO: use socket to send status to the client
|
|
|
|
|
async normalizeAllPublicPages() {
|
|
async normalizeAllPublicPages() {
|
|
|
- // const socket = this.crowi.socketIoService.getAdminSocket();
|
|
|
|
|
-
|
|
|
|
|
let isUnique;
|
|
let isUnique;
|
|
|
try {
|
|
try {
|
|
|
isUnique = await this._isPagePathIndexUnique();
|
|
isUnique = await this._isPagePathIndexUnique();
|
|
@@ -2658,7 +2655,6 @@ class PageService {
|
|
|
}
|
|
}
|
|
|
catch (err) {
|
|
catch (err) {
|
|
|
logger.error('V5 index normalization failed.', err);
|
|
logger.error('V5 index normalization failed.', err);
|
|
|
- // socket.emit('v5IndexNormalizationFailed', { error: err.message });
|
|
|
|
|
throw err;
|
|
throw err;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -2669,7 +2665,6 @@ class PageService {
|
|
|
}
|
|
}
|
|
|
catch (err) {
|
|
catch (err) {
|
|
|
logger.error('V5 initial miration failed.', err);
|
|
logger.error('V5 initial miration failed.', err);
|
|
|
- // socket.emit('v5InitialMirationFailed', { error: err.message });
|
|
|
|
|
|
|
|
|
|
throw err;
|
|
throw err;
|
|
|
}
|
|
}
|
|
@@ -2713,7 +2708,7 @@ class PageService {
|
|
|
* @param user To be used to filter pages to update. If null, only public pages will be updated.
|
|
* @param user To be used to filter pages to update. If null, only public pages will be updated.
|
|
|
* @returns Promise<void>
|
|
* @returns Promise<void>
|
|
|
*/
|
|
*/
|
|
|
- async normalizeParentRecursively(paths: string[], user: any | null): Promise<number> {
|
|
|
|
|
|
|
+ async normalizeParentRecursively(paths: string[], user: any | null, shouldEmit = false): Promise<number> {
|
|
|
const Page = mongoose.model('Page') as unknown as PageModel;
|
|
const Page = mongoose.model('Page') as unknown as PageModel;
|
|
|
|
|
|
|
|
const ancestorPaths = paths.flatMap(p => collectAncestorPaths(p, []));
|
|
const ancestorPaths = paths.flatMap(p => collectAncestorPaths(p, []));
|
|
@@ -2732,7 +2727,7 @@ class PageService {
|
|
|
|
|
|
|
|
const grantFiltersByUser: { $or: any[] } = Page.generateGrantCondition(user, userGroups);
|
|
const grantFiltersByUser: { $or: any[] } = Page.generateGrantCondition(user, userGroups);
|
|
|
|
|
|
|
|
- return this._normalizeParentRecursively(pathAndRegExpsToNormalize, ancestorPaths, grantFiltersByUser, user);
|
|
|
|
|
|
|
+ return this._normalizeParentRecursively(pathAndRegExpsToNormalize, ancestorPaths, grantFiltersByUser, user, shouldEmit);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private buildFilterForNormalizeParentRecursively(pathOrRegExps: (RegExp | string)[], publicPathsToNormalize: string[], grantFiltersByUser: { $or: any[] }) {
|
|
private buildFilterForNormalizeParentRecursively(pathOrRegExps: (RegExp | string)[], publicPathsToNormalize: string[], grantFiltersByUser: { $or: any[] }) {
|
|
@@ -2778,12 +2773,19 @@ class PageService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private async _normalizeParentRecursively(
|
|
private async _normalizeParentRecursively(
|
|
|
- pathOrRegExps: (RegExp | string)[], publicPathsToNormalize: string[], grantFiltersByUser: { $or: any[] }, user, count = 0, skiped = 0, isFirst = true,
|
|
|
|
|
|
|
+ pathOrRegExps: (RegExp | string)[],
|
|
|
|
|
+ publicPathsToNormalize: string[],
|
|
|
|
|
+ grantFiltersByUser: { $or: any[] },
|
|
|
|
|
+ user,
|
|
|
|
|
+ shouldEmit = false,
|
|
|
|
|
+ count = 0,
|
|
|
|
|
+ skiped = 0,
|
|
|
|
|
+ isFirst = true,
|
|
|
): Promise<number> {
|
|
): Promise<number> {
|
|
|
const BATCH_SIZE = 100;
|
|
const BATCH_SIZE = 100;
|
|
|
const PAGES_LIMIT = 1000;
|
|
const PAGES_LIMIT = 1000;
|
|
|
|
|
|
|
|
- const socket = this.crowi.socketIoService.getAdminSocket();
|
|
|
|
|
|
|
+ const socket = shouldEmit ? this.crowi.socketIoService.getAdminSocket() : null;
|
|
|
|
|
|
|
|
const Page = mongoose.model('Page') as unknown as PageModel;
|
|
const Page = mongoose.model('Page') as unknown as PageModel;
|
|
|
const { PageQueryBuilder } = Page;
|
|
const { PageQueryBuilder } = Page;
|
|
@@ -2805,7 +2807,7 @@ class PageService {
|
|
|
// Limit pages to get
|
|
// Limit pages to get
|
|
|
const total = await Page.countDocuments(matchFilter);
|
|
const total = await Page.countDocuments(matchFilter);
|
|
|
if (isFirst) {
|
|
if (isFirst) {
|
|
|
- socket.emit(SocketEventName.PMStarted, { total });
|
|
|
|
|
|
|
+ socket?.emit(SocketEventName.PMStarted, { total });
|
|
|
}
|
|
}
|
|
|
if (total > PAGES_LIMIT) {
|
|
if (total > PAGES_LIMIT) {
|
|
|
baseAggregation = baseAggregation.limit(Math.floor(total * 0.3));
|
|
baseAggregation = baseAggregation.limit(Math.floor(total * 0.3));
|
|
@@ -2912,13 +2914,13 @@ class PageService {
|
|
|
nextSkiped += res.result.writeErrors.length;
|
|
nextSkiped += res.result.writeErrors.length;
|
|
|
logger.info(`Page migration processing: (migratedPages=${res.result.nModified})`);
|
|
logger.info(`Page migration processing: (migratedPages=${res.result.nModified})`);
|
|
|
|
|
|
|
|
- socket.emit(SocketEventName.PMMigrating, { count: nextCount });
|
|
|
|
|
- socket.emit(SocketEventName.PMErrorCount, { skip: nextSkiped });
|
|
|
|
|
|
|
+ socket?.emit(SocketEventName.PMMigrating, { count: nextCount });
|
|
|
|
|
+ socket?.emit(SocketEventName.PMErrorCount, { skip: nextSkiped });
|
|
|
|
|
|
|
|
// Throw if any error is found
|
|
// Throw if any error is found
|
|
|
if (res.result.writeErrors.length > 0) {
|
|
if (res.result.writeErrors.length > 0) {
|
|
|
logger.error('Failed to migrate some pages', res.result.writeErrors);
|
|
logger.error('Failed to migrate some pages', res.result.writeErrors);
|
|
|
- socket.emit(SocketEventName.PMEnded, { isSucceeded: false });
|
|
|
|
|
|
|
+ socket?.emit(SocketEventName.PMEnded, { isSucceeded: false });
|
|
|
throw Error('Failed to migrate some pages');
|
|
throw Error('Failed to migrate some pages');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2926,7 +2928,7 @@ class PageService {
|
|
|
if (res.result.nModified === 0 && res.result.nMatched === 0) {
|
|
if (res.result.nModified === 0 && res.result.nMatched === 0) {
|
|
|
shouldContinue = false;
|
|
shouldContinue = false;
|
|
|
logger.error('Migration is unable to continue', 'parentPaths:', parentPaths, 'bulkWriteResult:', res);
|
|
logger.error('Migration is unable to continue', 'parentPaths:', parentPaths, 'bulkWriteResult:', res);
|
|
|
- socket.emit(SocketEventName.PMEnded, { isSucceeded: false });
|
|
|
|
|
|
|
+ socket?.emit(SocketEventName.PMEnded, { isSucceeded: false });
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
catch (err) {
|
|
catch (err) {
|
|
@@ -2948,11 +2950,11 @@ class PageService {
|
|
|
await streamToPromise(migratePagesStream);
|
|
await streamToPromise(migratePagesStream);
|
|
|
|
|
|
|
|
if (await Page.exists(matchFilter) && shouldContinue) {
|
|
if (await Page.exists(matchFilter) && shouldContinue) {
|
|
|
- return this._normalizeParentRecursively(pathOrRegExps, publicPathsToNormalize, grantFiltersByUser, user, nextCount, nextSkiped, false);
|
|
|
|
|
|
|
+ return this._normalizeParentRecursively(pathOrRegExps, publicPathsToNormalize, grantFiltersByUser, user, shouldEmit, nextCount, nextSkiped, false);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// End
|
|
// End
|
|
|
- socket.emit(SocketEventName.PMEnded, { isSucceeded: true });
|
|
|
|
|
|
|
+ socket?.emit(SocketEventName.PMEnded, { isSucceeded: true });
|
|
|
|
|
|
|
|
return nextCount;
|
|
return nextCount;
|
|
|
}
|
|
}
|