Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/import_entities/import_groups/graphql/services')
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js45
-rw-r--r--app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js68
2 files changed, 113 insertions, 0 deletions
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
new file mode 100644
index 00000000000..f752ecc8cd6
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/source_groups_manager.js
@@ -0,0 +1,45 @@
+import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import produce from 'immer';
+import ImportSourceGroupFragment from '../fragments/bulk_import_source_group_item.fragment.graphql';
+
+function extractTypeConditionFromFragment(fragment) {
+ return fragment.definitions[0]?.typeCondition.name.value;
+}
+
+function generateGroupId(id) {
+ return defaultDataIdFromObject({
+ __typename: extractTypeConditionFromFragment(ImportSourceGroupFragment),
+ id,
+ });
+}
+
+export class SourceGroupsManager {
+ constructor({ client }) {
+ this.client = client;
+ }
+
+ findById(id) {
+ const cacheId = generateGroupId(id);
+ return this.client.readFragment({ fragment: ImportSourceGroupFragment, id: cacheId });
+ }
+
+ update(group, fn) {
+ this.client.writeFragment({
+ fragment: ImportSourceGroupFragment,
+ id: generateGroupId(group.id),
+ data: produce(group, fn),
+ });
+ }
+
+ updateById(id, fn) {
+ const group = this.findById(id);
+ this.update(group, fn);
+ }
+
+ setImportStatus(group, status) {
+ this.update(group, sourceGroup => {
+ // eslint-disable-next-line no-param-reassign
+ sourceGroup.status = status;
+ });
+ }
+}
diff --git a/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js b/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js
new file mode 100644
index 00000000000..5d2922b0ba8
--- /dev/null
+++ b/app/assets/javascripts/import_entities/import_groups/graphql/services/status_poller.js
@@ -0,0 +1,68 @@
+import gql from 'graphql-tag';
+import createFlash from '~/flash';
+import { s__ } from '~/locale';
+import bulkImportSourceGroupsQuery from '../queries/bulk_import_source_groups.query.graphql';
+import { STATUSES } from '../../../constants';
+import { SourceGroupsManager } from './source_groups_manager';
+
+const groupId = i => `group${i}`;
+
+function generateGroupsQuery(groups) {
+ return gql`{
+ ${groups
+ .map(
+ (g, idx) =>
+ `${groupId(idx)}: group(fullPath: "${g.import_target.target_namespace}/${
+ g.import_target.new_name
+ }") { id }`,
+ )
+ .join('\n')}
+ }`;
+}
+
+export class StatusPoller {
+ constructor({ client, interval }) {
+ this.client = client;
+ this.interval = interval;
+ this.timeoutId = null;
+ this.groupManager = new SourceGroupsManager({ client });
+ }
+
+ startPolling() {
+ if (this.timeoutId) {
+ return;
+ }
+
+ this.checkPendingImports();
+ }
+
+ stopPolling() {
+ clearTimeout(this.timeoutId);
+ this.timeoutId = null;
+ }
+
+ async checkPendingImports() {
+ try {
+ const { bulkImportSourceGroups } = this.client.readQuery({
+ query: bulkImportSourceGroupsQuery,
+ });
+ const groupsInProgress = bulkImportSourceGroups.filter(g => g.status === STATUSES.STARTED);
+ if (groupsInProgress.length) {
+ const { data: results } = await this.client.query({
+ query: generateGroupsQuery(groupsInProgress),
+ fetchPolicy: 'no-cache',
+ });
+ const completedGroups = groupsInProgress.filter((_, idx) => Boolean(results[groupId(idx)]));
+ completedGroups.forEach(group => {
+ this.groupManager.setImportStatus(group, STATUSES.FINISHED);
+ });
+ }
+ } catch (e) {
+ createFlash({
+ message: s__('BulkImport|Update of import statuses with realtime changes failed'),
+ });
+ } finally {
+ this.timeoutId = setTimeout(() => this.checkPendingImports(), this.interval);
+ }
+ }
+}