Skip to content

Commit ac38333

Browse files
authored
Support global request batch size (#1053)
Closes: #1045 Currently the /batch endpoint send multiple requests in the with the number of objects equal to batchSize (default 20). I believe batchSize was added to reduce server load during the parse.com days. Having batchSize will make result in a certain amount of overhead for your client. This PR will allow you to decrease the number of request which may result in saving resources.
1 parent 6dc6e5c commit ac38333

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

src/CoreManager.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ const config: Config & { [key: string]: mixed } = {
175175
!!process.versions.node &&
176176
!process.versions.electron),
177177
REQUEST_ATTEMPT_LIMIT: 5,
178+
REQUEST_BATCH_SIZE: 20,
178179
REQUEST_HEADERS: {},
179180
SERVER_URL: 'https://api.parse.com/1',
180181
SERVER_AUTH_TYPE: null,

src/ParseObject.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ type SaveOptions = FullOptions & {
5959
cascadeSave?: boolean
6060
}
6161

62-
const DEFAULT_BATCH_SIZE = 20;
63-
6462
// Mapping of class names to constructors, so we can populate objects from the
6563
// server with appropriate subclasses of ParseObject
6664
const classMap = {};
@@ -2141,7 +2139,7 @@ const DefaultController = {
21412139
},
21422140

21432141
async destroy(target: ParseObject | Array<ParseObject>, options: RequestOptions): Promise<Array<void> | ParseObject> {
2144-
const batchSize = (options && options.batchSize) ? options.batchSize : DEFAULT_BATCH_SIZE;
2142+
const batchSize = (options && options.batchSize) ? options.batchSize : CoreManager.get('REQUEST_BATCH_SIZE');
21452143
const localDatastore = CoreManager.getLocalDatastore();
21462144

21472145
const RESTController = CoreManager.getRESTController();
@@ -2216,7 +2214,7 @@ const DefaultController = {
22162214
},
22172215

22182216
save(target: ParseObject | Array<ParseObject | ParseFile>, options: RequestOptions) {
2219-
const batchSize = (options && options.batchSize) ? options.batchSize : DEFAULT_BATCH_SIZE;
2217+
const batchSize = (options && options.batchSize) ? options.batchSize : CoreManager.get('REQUEST_BATCH_SIZE');
22202218
const localDatastore = CoreManager.getLocalDatastore();
22212219
const mapIdForPin = {};
22222220

src/__tests__/Parse-test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,11 @@ describe('Parse module', () => {
126126
expect(CoreManager.get('ENCRYPTED_KEY')).toBe('My Super secret key');
127127
expect(Parse.secret).toBe('My Super secret key');
128128
});
129+
130+
it('can set and get request batch size', () => {
131+
expect(CoreManager.get('REQUEST_BATCH_SIZE')).toBe(20);
132+
CoreManager.set('REQUEST_BATCH_SIZE', 4);
133+
expect(CoreManager.get('REQUEST_BATCH_SIZE')).toBe(4);
134+
CoreManager.set('REQUEST_BATCH_SIZE', 20);
135+
});
129136
});

src/__tests__/ParseObject-test.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,69 @@ describe('ParseObject', () => {
17441744
jest.runAllTicks();
17451745
});
17461746

1747+
it('can saveAll with global batchSize', async (done) => {
1748+
const xhrs = [];
1749+
for (let i = 0; i < 2; i++) {
1750+
xhrs[i] = {
1751+
setRequestHeader: jest.fn(),
1752+
open: jest.fn(),
1753+
send: jest.fn(),
1754+
status: 200,
1755+
readyState: 4
1756+
};
1757+
}
1758+
let current = 0;
1759+
RESTController._setXHR(function() { return xhrs[current++]; });
1760+
const objects = [];
1761+
for (let i = 0; i < 22; i++) {
1762+
objects[i] = new ParseObject('Person');
1763+
}
1764+
ParseObject.saveAll(objects).then(() => {
1765+
expect(xhrs[0].open.mock.calls[0]).toEqual(
1766+
['POST', 'https://api.parse.com/1/batch', true]
1767+
);
1768+
expect(xhrs[1].open.mock.calls[0]).toEqual(
1769+
['POST', 'https://api.parse.com/1/batch', true]
1770+
);
1771+
done();
1772+
});
1773+
jest.runAllTicks();
1774+
await flushPromises();
1775+
1776+
xhrs[0].responseText = JSON.stringify([
1777+
{ success: { objectId: 'pid0' } },
1778+
{ success: { objectId: 'pid1' } },
1779+
{ success: { objectId: 'pid2' } },
1780+
{ success: { objectId: 'pid3' } },
1781+
{ success: { objectId: 'pid4' } },
1782+
{ success: { objectId: 'pid5' } },
1783+
{ success: { objectId: 'pid6' } },
1784+
{ success: { objectId: 'pid7' } },
1785+
{ success: { objectId: 'pid8' } },
1786+
{ success: { objectId: 'pid9' } },
1787+
{ success: { objectId: 'pid10' } },
1788+
{ success: { objectId: 'pid11' } },
1789+
{ success: { objectId: 'pid12' } },
1790+
{ success: { objectId: 'pid13' } },
1791+
{ success: { objectId: 'pid14' } },
1792+
{ success: { objectId: 'pid15' } },
1793+
{ success: { objectId: 'pid16' } },
1794+
{ success: { objectId: 'pid17' } },
1795+
{ success: { objectId: 'pid18' } },
1796+
{ success: { objectId: 'pid19' } },
1797+
]);
1798+
xhrs[0].onreadystatechange();
1799+
jest.runAllTicks();
1800+
await flushPromises();
1801+
1802+
xhrs[1].responseText = JSON.stringify([
1803+
{ success: { objectId: 'pid20' } },
1804+
{ success: { objectId: 'pid21' } },
1805+
]);
1806+
xhrs[1].onreadystatechange();
1807+
jest.runAllTicks();
1808+
});
1809+
17471810
it('returns the first error when saving an array of objects', async (done) => {
17481811
const xhrs = [];
17491812
for (let i = 0; i < 2; i++) {

0 commit comments

Comments
 (0)