Skip to content

Instantly share code, notes, and snippets.

@JasonCust
Last active February 21, 2018 03:12
Show Gist options
  • Save JasonCust/9b75309c010d771bf71b4aa56e46129d to your computer and use it in GitHub Desktop.
Save JasonCust/9b75309c010d771bf71b4aa56e46129d to your computer and use it in GitHub Desktop.
Concurrent Updates: Full vs Partial Objects.
import createDb from './database.js';
import { randomWait, log } from './helper.js';
const db = createDb();
// Current middleware approach
const logger = log('Full');
// Simulated two concurrent fetch and save requests
Promise.all([
db.get('records', 2).then(async record => {
// Simulate a delay
const wait = await randomWait();
record.foo = 'Update';
return db.save('records', 2, record);
}),
db.get('records', 2).then(async record => {
// Simulate a delay
const wait = await randomWait();
record.bar = 'Update';
return db.save('records', 2, record);
}),
]).then(
results => Promise.all(results.concat(db.get('records', 2)))
).then(
([firstUpdate, secondUpdate, curRecord]) => logger({firstUpdate, secondUpdate, curRecord})
);
import createDb from './database.js';
import { randomWait, log } from './helper.js';
const db = createDb();
// Current middleware approach
const logger = log('Partial');
// Simulated two concurrent fetch and update requests
Promise.all([
db.get('records', 2).then(async record => {
// Simulate a delay
const wait = await randomWait();
return db.save('records', 2, { foo: 'Update' });
}),
db.get('records', 2).then(async record => {
// Simulate a delay
const wait = await randomWait();
return db.save('records', 2, { bar: 'Update' });
}),
]).then(
results => Promise.all(results.concat(db.get('records', 2)))
).then(
([firstUpdate, secondUpdate, curRecord]) => logger({firstUpdate, secondUpdate, curRecord})
);
// The "database"
// Records Collection
export const records = [
{ id: 1, foo: 'expedita odio fugiat', bar: 'eos natus pariatur' },
{ id: 2, foo: 'aspernatur reiciendis dolores', bar: 'illo delectus ut' },
{ id: 3, foo: 'rerum tempore minima', bar: 'qui hic dolor' }
];
export const db = {
load: async function load(collection, items) {
this[collection] = items.map(item => ({...item}));
},
// Simulate an async get request
get: async function get(collection, id) {
const obj = this[collection].find(doc => doc.id === id);
// Shallow clone doc to break reference to collection object
return {...obj};
},
// Simulate an async save request
save: async function save(collection, id, obj) {
const index = this[collection].findIndex(doc => doc.id === id);
// "Store" record
return this[collection][index] = { ...this[collection][index], ...obj };
}
};
export default () => { const dbCopy = {...db}; dbCopy.load('records', records); return dbCopy; };
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Middleware vs Pipeline</title>
<script type="module" src="helper.js"></script>
<script type="module" src="database.js"></script>
<script type="module" src="concurrent-full-update-example.js"></script>
<script type="module" src="concurrent-partial-update-example.js"></script>
</head>
<body>
<h1>Open the console...</h1>
</body>
</html>
// Generate random delay
export function randomWait() {
return new Promise(resolve => {
setTimeout(resolve, Math.ceil(Math.random() * 1000));
});
}
// Name-spaced logger function
export const log = type => (...args) => console.log(`[${type}]`, ...args);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment