diff --git a/tests/domain-service.test.js b/tests/domain-service.test.js index 554089466..19154db6e 100644 --- a/tests/domain-service.test.js +++ b/tests/domain-service.test.js @@ -141,46 +141,6 @@ describe('Domain service', () => { }); }); - describe('setHosts', () => { - it('should resolve with a list of hosts', async () => { - const records = [ - { name: 'xx', type: 'CNAME', address: 'fck.com' }, - { name: 'xx', type: 'A', address: '111.1.1212.1' }, - { name: 'foo', type: 'URL', address: 'https://google.com' }, - { name: 'foo1', type: 'URL', address: 'https://duck.com' }, - ]; - - const addZone = jest.fn(async () => {}); - const addRedir = jest.fn(async () => {}); - - const mockDomainService = getDomainService({ cpanel: getCpanel({ addZone, addRedir }) }); - await mockDomainService.setHosts(records); - - expect(addZone).toBeCalledTimes(2); - expect(addRedir).toBeCalledTimes(2); - expect(addZone.mock.calls.map(R.head)).toEqual([ - { name: 'xx', type: 'CNAME', address: 'fck.com' }, - { name: 'xx', type: 'A', address: '111.1.1212.1' }, - ]); - expect(addRedir.mock.calls.map(R.head)).toEqual([ - { - domain: 'foo.booboo.xyz', - redirect: 'https://google.com', - redirect_wildcard: 1, - redirect_www: 0, - type: 'permanent', - }, - { - domain: 'foo1.booboo.xyz', - redirect: 'https://duck.com', - redirect_wildcard: 1, - redirect_www: 0, - type: 'permanent', - }, - ]); - }); - }); - describe('updateHosts', () => { it('should append new hosts with existing ones and set it', async () => { const zones = [ diff --git a/utils/domain-service.js b/utils/domain-service.js index 5ffe0a8e8..9aacbee6e 100644 --- a/utils/domain-service.js +++ b/utils/domain-service.js @@ -2,7 +2,7 @@ const R = require('ramda'); const { cpanel } = require('./lib/cpanel'); const { DOMAIN_DOMAIN } = require('./constants'); -const flattenPromise = xs => Promise.all(xs); +const promiseAll = xs => Promise.all(xs); const recordToRedirection = ({ name, address }) => ({ domain: `${name}.${DOMAIN_DOMAIN}`, @@ -58,17 +58,33 @@ const diffRecords = (oldRecords, newRecords) => { }, { add: [], edit: [] }); }; +const lazyTask = fn => data => () => fn(data); + +const batchLazyTasks = count => tasks => tasks.reduce((batches, task) => { + if (batches.length === 0) return [[task]]; + + const full = R.init(batches); + const last = R.last(batches); + + if (last.length >= count) return [...batches, [task]]; + return [...full, [...last, task]]; +}, []); + +const executeBatch = (batches) => batches.reduce((promise, batch) => { + return promise.then(() => Promise.all(batch.map(fn => fn()))); +}, Promise.resolve()); + const getDomainService = ({ cpanel }) => { let hostList = []; const fetchZoneRecords = () => cpanel.zone.fetch().then(R.map(zoneToRecord)); const fetchRedirections = () => cpanel.redirection.fetch().then(R.map(redirectionToRecord)); - const addZoneRecord = R.compose(cpanel.zone.add, recordToZone); - const addRedirection = R.compose(cpanel.redirection.add, recordToRedirection); + const addZoneRecord = lazyTask(R.compose(cpanel.zone.add, recordToZone)); + const addRedirection = lazyTask(R.compose(cpanel.redirection.add, recordToRedirection)); - const editZoneRecord = R.compose(cpanel.zone.edit, recordToZone); - const editRedirection = R.compose(cpanel.redirection.edit, recordToRedirection); + const editZoneRecord = lazyTask(R.compose(cpanel.zone.edit, recordToZone)); + const editRedirection = lazyTask(R.compose(cpanel.redirection.edit, recordToRedirection)); const getHosts = async () => { if (hostList.length) return hostList; @@ -79,11 +95,11 @@ const getDomainService = ({ cpanel }) => { return list; }; - const addRecords = R.compose(flattenPromise, R.map(R.cond([ + const addRecords = R.compose(batchLazyTasks(10), R.map(R.cond([ [ R.propEq('type', 'URL'), addRedirection ], [ R.T, addZoneRecord ], ]))); - const editRecords = R.compose(flattenPromise, R.map(R.cond([ + const editRecords = R.compose(batchLazyTasks(10), R.map(R.cond([ [ R.propEq('type', 'URL'), editRedirection ], [ R.T, editZoneRecord ], ]))); @@ -92,10 +108,10 @@ const getDomainService = ({ cpanel }) => { const remoteHostList = await getHosts(); const { add, edit } = diffRecords(remoteHostList, hosts); - return Promise.all([ addRecords(add), editRecords(edit) ]); + return executeBatch(addRecords(add).concat(editRecords(edit))); }; - return { getHosts, setHosts: addRecords, updateHosts }; + return { getHosts, updateHosts }; }; const domainService = getDomainService({ cpanel });