Last active
March 6, 2017 22:15
-
-
Save crazy4groovy/aaf5f82a22c3fc6e1c3e5fb58c591f8f to your computer and use it in GitHub Desktop.
Parse EC2 spot prices; store in an elasticsearch DB as a timeseries dataset.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('http').globalAgent.maxSockets = 10 | |
setInterval(main, (5 * 60 * 1000) - 6) // rinse-and-repeat every 5 minutes | |
main() // kick start! | |
function main () { | |
const req = require('request-promise') | |
const co = require('co') | |
const oO = require('eyes').inspector({maxLength: 99999}) | |
const urls = { | |
spot: 'https://spot-price.s3.amazonaws.com/spot.js', | |
spotblocks_linux: 'https://spot-price.s3.amazonaws.com/spotblocks-generic.js', | |
spotblocks_windows: 'https://spot-price.s3.amazonaws.com/spotblocks-windows.js' | |
} | |
co(function * run () { | |
const timestamp = Date.now() | |
oO(timestamp) | |
for (let group in urls) { | |
oO(group, new Date()) | |
const url = urls[group] | |
const data = yield getData(url) | |
const prices = parseData(group, timestamp, data) | |
yield postPrices(prices) | |
} | |
oO('COMPLETED!', ((Date.now() - timestamp) / 1000) + 's') | |
}) | |
function scrub (a) { | |
return a.replace(/\W+/g, '_') | |
} | |
function * getData (url) { | |
const resp = yield req(url) | |
return JSON.parse(resp.substring(9, resp.length - 2)) | |
} | |
function parseData (group, timestamp, resp) { | |
const prices = [] | |
resp.config.regions.forEach((i1) => { | |
const region = scrub(i1.region) | |
i1.instanceTypes.forEach((i2) => { | |
const type = scrub(i2.type) | |
i2.sizes.forEach((i3) => { | |
const size = scrub(i3.size) | |
i3.valueColumns.forEach((i4) => { | |
const price = +(i4.prices.USD) | |
if (!price) return | |
const name = scrub(i4.name) | |
prices.push({ group, region, type, size, price_usd: price, name, timestamp }) | |
}) | |
}) | |
}) | |
}) | |
return prices | |
} | |
function * postPrice (body) { | |
try { | |
yield req.post({uri: 'http://192.168.100.1:9200/aws/ec2_spot/', body, json: true, timeout: 60000}) | |
} catch (err) { | |
oO(err) | |
return | |
} | |
} | |
function * postPrices (prices) { | |
let i = 0 | |
for (let body of prices) { | |
if (++i % 40 === 0) { | |
yield postPrice(body) // pause | |
} else { | |
postPrice(body).next() // fire and forget | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"mappings": { | |
"ec2_spot": { | |
"properties": { | |
"group": { | |
"type": "string" | |
}, | |
"name": { | |
"type": "string" | |
}, | |
"price_usd": { | |
"type": "double" | |
}, | |
"region": { | |
"type": "string" | |
}, | |
"size": { | |
"type": "string" | |
}, | |
"timestamp": { | |
"type": "date", | |
"format": "epoch_millis" | |
}, | |
"type": { | |
"type": "string" | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think/hope I got all the memory leaks ironed out :)