go from batch processing to stream processing input: - config -> originTimestamp, timeWindow, timestamps, testDuration - json files being generated by weather-station (./load-generation/results) output: - FINAL BUCKET OBJECT: - key: stepName-normalizedTimestamp - value is an object. Inside the object, property is unique userId with their normalized metrics - value: an object with 1 or more userIds as keys: value: { metrics: { normalizedResponseTime: 108 }} - track current upperBound of the current normalizedTimestamp - as soon as we see a raw timestamp > upperbound, package up the current normalizedTimestamp's datapoints Algorithm: - const initialOffset = 15s - polling time after initialOffset = 15s - global object: const normalizedTimestamps = config.timestamps; - set initialOffset = 15_000 - let shouldRunningNormalization = true - let noNextDataPoint = false - inside the while loop: (polling every 15s) while (shouldRunningNormalization) - let shouldProcess = false - if (normalizedTimestamps.length === 1) { shouldRunningNormalization = false break } - calculate the lowerBound & upperBound of normalizedTimestamps[0] - let shouldProcess = false - loop through each json file generated by weather-station - if the stepStartTime >= upperBound { shouldProcess = true noNextDataPoint = false break } - if (shouldProcess) { - only process all data points in normalizedTimestamps[0] (delete json files after process as well) - only data points with stepStartTime between lowerBound & upperBound (>=lowerBound & < upperBound) - build filterdBucket - build finalBucket - send only the data points from normalizedTimestamps[0] to S3 bucket - chop off the normalizedTimestamps[0] } else { if (noNextDataPoint) { - only process all data points in normalizedTimestamps[0] (delete json files after process as well) - only data points with stepStartTime between lowerBound & upperBound (>=lowerBound & < upperBound) - build filterdBucket - build finalBucket - send only the data points from normalizedTimestamps[0] to S3 bucket - chop off the normalizedTimestamps[0] } else { noNextDataPoint = true } } - process the last batch new metrics pass/fail PEDAC: - filteredBucket: { '1635530769000': [ { userId: 'dn34u94', stepStartTime: 1635530769571, metrics: [Object], // Object has the form of { responseTime: 108 } // Object has the form of { responseTime: Number || null, passed: true || false} stepName: 'Go to bin' }, { userId: 'dn34u94', stepStartTime: 1635530769069, metrics: [Object], stepName: 'Load main page' } ], '1635530771000': [ { userId: 'dn34u94', stepStartTime: 1635530771903, metrics: [Object], stepName: 'Go to bin' }, { userId: 'dn34u94', stepStartTime: 1635530771384, metrics: [Object], stepName: 'Load main page' } ], } Output for finalBucket: { metrics: { normalizedResponseTime: Number, passCount: Number, failCount: Number, transactionRate: Number }, sampleCount: Number }