Skip to content

Commit

Permalink
JS SDK support for timeouts and retries on startup (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
facundocabrera authored Jun 24, 2016
1 parent 730bab1 commit 4a35df5
Show file tree
Hide file tree
Showing 101 changed files with 1,627 additions and 630 deletions.
40 changes: 40 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
## 6.0.0 (June 24, 2016)

* In the browser land we allow quick retries before start using the refresh
rates defined for segments and splits, plus the possibility of receive an
event when the SDK is taking to much time to startup.

```html
<script src="//cdn.split.io/sdk/split-6.0.0.min.js"></script>
<script>
var sdk = splitio({
core: {
authorizationKey: '<your-token>',
key: '[email protected]'
},
startup: {
// timeout an *initial* request after 0.8 seconds (only affects startup)
requestTimeoutBeforeReady: 0.8,
// how many quick retries are allowed before use the schedulers refresh
// rates (only affects startup)
retriesOnFailureBeforeReady: 1,
// maximum amount of seconds we are going to wait for the ready event
readyTimeout: 1.5
}
});

sdk.on(sdk.Event.SDK_READY_TIMED_OUT, function () {
// this callback will be called after 1.5 seconds if and only if the SDK
// is not ready for that time
});

sdk.on(sdk.Event.SDK_READY, function () {
// the SDK is ready for start making evaluations with your data
});

sdk.on(sdk.Event.SDK_UPDATE, function () {
// fired each time the SDK state change
});
</script>
```

## 5.1.1 (June 13, 2016)

* None API changes. Bug fixing release.
Expand Down
9 changes: 9 additions & 0 deletions NEWS.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 6.0.0 (June 24, 2016)

* In the browser land, it's important to have quick retries before after a
stretch timeouts. We added new configurations to handle this.
* Added the concept of 'ready timeout', so you could take a controlled action if
the SDK is taking too much time doing the startup.
* Fixed few bugs, specially for the browser release.
* `.ready()` method is deprecated in favor of `sdk.on(sdk.Event.SDK_READY, function onReady() { do something; })`

## 5.1.1 (June 13, 2016)

* Added missing support for events in offline mode (NodeJS and Browser).
Expand Down
3 changes: 3 additions & 0 deletions crazy-cdn/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015-node4"]
}
1 change: 1 addition & 0 deletions crazy-cdn/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/lib
28 changes: 28 additions & 0 deletions crazy-cdn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Crazy CDN

The concept is a proxy which add delays and eventually errors in the services
using express middlewares.

## How to run

1. `nvm install v4`
2. `nvm use v4`
3. `npm install`
4. `npm run b`
5. `npm start`
6. `The proxy server is running in localhost:3000`

By default the target is hardcoded to be staging servers, but you could change
that quickly.

> HTTPS is disabled using a "un-secure" scheme because we are a man in the
middle.

## How to development

1. `nvm install v4`
2. `nvm use v4`
3. `npm install`
4. `npm run w` => live recompilation on changes
5. `npm run m` => live nodejs reload after recompilation changes
6. `The proxy server is running in localhost:3000`
30 changes: 30 additions & 0 deletions crazy-cdn/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@splitsoftware/crazy-cdn",
"version": "1.0.0",
"description": "Crazy CDN",
"readme": "README.md",
"author": "Facundo Cabrera <[email protected]>",
"homepage": "https://github.com/splitio/javascript-client",
"license": "Apache-2.0",
"repository": "https://github.com/splitio/javascript-client/tree/master/crazy-cdn",
"main": "lib/index.js",
"scripts": {
"start": "node lib/index.js",
"m": "nodemon lib/index.js",
"b": "babel src --out-dir lib",
"w": "babel src --out-dir lib -w"
},
"engines": {
"node": "4.4.3",
"npm": "3.9.3"
},
"dependencies": {
"express": "^4.14.0",
"http-proxy": "^1.14.0"
},
"devDependencies": {
"babel-cli": "^6.10.1",
"babel-preset-es2015-node4": "^2.1.0",
"nodemon": "^1.9.2"
}
}
38 changes: 38 additions & 0 deletions crazy-cdn/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const express = require('express');
const app = express();

const httpProxy = require('http-proxy');
const proxy = httpProxy.createProxyServer({});

app.use(function(err, req, res, next) {
res.status(503).send(JSON.stringigy(err));
});

app.use(function delay(req, res, next) {
setTimeout(next, Math.random() * 3000);
});

app.use(function internalError(req, res, next) {
// if (Math.random() > 0.8) {
if (false) {
res.status(500).send({
status: 500,
message: 'internal error',
type:'internal'
});
} else {
next();
}
});

app.all('/*', function(req, res) {
proxy.web(req, res, {
target: 'https://sdk-aws-staging.split.io',
secure: false,
changeOrigin: true
});
});

app.listen(3000, function () {
console.log('Crazy proxy at 3000 port');
});
5 changes: 4 additions & 1 deletion demos/browser-split/offline/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ console.info(
// The following code will be evaluated once the engine finalice the
// initialization
//
sdk.ready().then(function () {
sdk.on(sdk.Event.SDK_READY, function onSDKReady() {
//
// Some simple cases for my defined features
//
Expand All @@ -48,3 +48,6 @@ sdk.ready().then(function () {
"<= The expected answer based on the definition before is 'delta'"
);
});

// just to show up the deprecated message
sdk.ready().then(function() {});
2 changes: 1 addition & 1 deletion demos/browser-split/offline/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div id="main">
Hello SPLIT! => Please use the devTools to start testing the engine!
</div>
<script src="//cdn.split.io/sdk/split-5.1.1.js"></script>
<script src="/splitio/split-6.0.0.js"></script>
<script src="/offline/app.js"></script>
</body>
</html>
49 changes: 35 additions & 14 deletions demos/browser-split/online/app.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,51 @@
'use strict';

console.log('SPLIT DEMO!');

//
// Bellow you will see how you could define features and the defaults treatments
// for each one.
//
// NOTICE: there is NONE asyncronous initialization in offline mode, because you
// are providing the default feedback of the engine.
//

var sdk = splitio({
core: {
authorizationKey: '29lsbc79peklpksdto0a90s2e3u1agv8vqm2', // change this with your api token
key: '4a2c4490-ced1-11e5-9b97-d8a25e8b1578' // change this with your user key
}/*,
// change this with your api token
authorizationKey: '5p2c0r4so20ill66lm35i45h6pkvrd2skmib',
// change this with your user key
key: '1f84e5ddb06a3e66145ccfc1aac247'
},
scheduler: {
featuresRefreshRate: 1, // fetch feature updates each 1 sec
segmentsRefreshRate: 1, // fetch segment updates each 1 sec
metricsRefreshRate: 30, // publish metrics each 30 sec
impressionsRefreshRate: 30 // publish evaluations each 30 sec
}*/
// fetch feature updates each 15 sec
featuresRefreshRate: 15,
// fetch segment updates each 15 sec
segmentsRefreshRate: 15,
// publish metrics each 15 sec
metricsRefreshRate: 15,
// publish evaluations each 15 sec
impressionsRefreshRate: 15
},
urls: {
sdk: 'https://sdk-aws-staging.split.io/api',
events: 'https://events-aws-staging.split.io/api'
}
});

console.info( sdk.getTreatment('early_evaluation') , '<= We are asking for a feature before the engine is ready');
console.assert(
sdk.getTreatment('in_five_keys') === 'control'
);

sdk.on(sdk.Event.SDK_READY_TIMED_OUT, function onTimeout() {
console.log('SDK ready timeout');
});

sdk.ready().then(function () {
console.info( sdk.getTreatment('js_sdk'), '<= This answer depends on split configurations' );
sdk.on(sdk.Event.SDK_READY, function onSDKReady() {
console.assert(sdk.getTreatment('in_five_keys') === 'activated');
});

sdk.on(sdk.Event.SDK_UPDATE, function onSDKUpdate() {
console.log(sdk.getTreatment('in_five_keys'));
console.log(sdk.getTreatment('in_ten_keys'));
});

// just to show up the deprecated message
sdk.ready().then(function () {});
2 changes: 1 addition & 1 deletion demos/browser-split/online/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div id="main">
Hello SPLIT! => Please use the devTools to start testing the engine!
</div>
<script src="https://cdn.split.io/sdk/split-5.1.1.js"></script>
<script src="/splitio/split-6.0.0.js"></script>
<script src="/online/app.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion demos/browser-split/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
"http-server": "^0.9.0"
},
"devDependencies": {
"@splitsoftware/splitio-browser": "5.1.1"
"@splitsoftware/splitio-browser": "6.0.0"
}
}
10 changes: 5 additions & 5 deletions demos/express-split/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ if (process.env.SPLIT_SDK_MODE === 'offline') {
} else {
sdk = splitio({
core: {
authorizationKey: '5p2c0r4so20ill66lm35i45h6pkvrd2skmib' // nodejs environment
authorizationKey: '5p2c0r4so20ill66lm35i45h6pkvrd2skmib'
},
urls: {
sdk: 'https://sdk-aws-staging.split.io/api',
events: 'https://events-aws-staging.split.io/api'
},
scheduler: {
featuresRefreshRate: 5, // fetch feature updates each 1 sec
segmentsRefreshRate: 5, // fetch segment updates each 1 sec
metricsRefreshRate: 10, // publish metrics each 30 sec
impressionsRefreshRate: 10 // publish evaluations each 30 sec
featuresRefreshRate: 15,
segmentsRefreshRate: 15,
metricsRefreshRate: 15,
impressionsRefreshRate: 15
}
});
}
Expand Down
5 changes: 3 additions & 2 deletions demos/express-split/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
"repository": "https://github.com/splitio/javascript-client/tree/master/demo/express-split",
"main": "index.js",
"scripts": {
"start": "DEBUG=splitio* node index.js"
"start": "node index.js",
"debug": "DEBUG=splitio* node index.js"
},
"engines": {
"node": ">=0.12",
"npm": "3.x"
},
"dependencies": {
"@splitsoftware/splitio": "5.1.1",
"@splitsoftware/splitio": "6.0.0",
"express": "^4.13.3"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"watch": "babel es6 --out-dir lib --watch"
},
"dependencies": {
"@splitsoftware/splitio": "5.1.1",
"@splitsoftware/splitio-utils": "5.1.1",
"@splitsoftware/splitio": "6.0.0",
"@splitsoftware/splitio-utils": "6.0.0",
"babel-runtime": "^5.8.35",
"core-js": "^1.2.6"
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"license": "Apache-2",
"version": "5.1.1",
"version": "6.0.0",
"scripts": {
"lint": "./scripts/lint.sh",
"install-all": "./scripts/install-all.sh",
Expand Down
4 changes: 2 additions & 2 deletions packages/splitio-browser/bin/bundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const debug = browserify({ debug: true });
debug.add(splitSource);
debug.transform(envify({
_: 'purge',
NODE_ENV: process.env.NODE_ENV || 'production'
NODE_ENV: 'development'
}), { global: true })
.bundle()
.pipe(fs.createWriteStream(debugBundlePath));
Expand All @@ -95,7 +95,7 @@ const prod = browserify();
prod.add(splitSource);
prod.transform(envify({
_: 'purge',
NODE_ENV: process.env.NODE_ENV || 'production'
NODE_ENV: 'production'
}), { global: true })
.bundle()
.pipe(fs.createWriteStream(productionBundlePath))
Expand Down
4 changes: 2 additions & 2 deletions packages/splitio-browser/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@splitsoftware/splitio-browser",
"version": "5.1.1",
"version": "6.0.0",
"description": "Split SDK tools for the browser",
"author": "Facundo Cabrera <[email protected]>",
"homepage": "https://github.com/splitio/javascript-client",
Expand All @@ -25,7 +25,7 @@
"sdk"
],
"dependencies": {
"@splitsoftware/splitio": "5.1.1",
"@splitsoftware/splitio": "6.0.0",
"browserify": "^13.0.0",
"browserify-derequire": "^0.9.4",
"bundle-collapser": "^1.2.1",
Expand Down
17 changes: 12 additions & 5 deletions packages/splitio-cache/es6/ds/mySegments.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**/
const timeout = require('@splitsoftware/splitio-utils/lib/promise/timeout');

const mySegmentsService = require('@splitsoftware/splitio-services/lib/mySegments');
const mySegmentsRequest = require('@splitsoftware/splitio-services/lib/mySegments/get');

const mySegmentMutationsFactory = require('../mutators/mySegments');

function mySegmentsDataSource(settings) {
return mySegmentsService(mySegmentsRequest(settings))
.then(resp => resp.json())
.then(json => mySegmentMutationsFactory(json.mySegments.map(segment => segment.name)))
.catch(() => false);
function mySegmentsDataSource(settings, shouldApplyTimeout = false) {
let requestPromise = mySegmentsService(mySegmentsRequest(settings));

if (shouldApplyTimeout) {
requestPromise = timeout(settings.startup.requestTimeoutBeforeReady, requestPromise);
}

return requestPromise.then(resp => resp.json()).then(
json => mySegmentMutationsFactory(json.mySegments.map(segment => segment.name))
);
}

module.exports = mySegmentsDataSource;
Loading

0 comments on commit 4a35df5

Please sign in to comment.