Skip to content

Commit

Permalink
GAPI-24749: major documentation update, cache and retry rework
Browse files Browse the repository at this point in the history
  • Loading branch information
cadgerfeast committed Nov 4, 2020
1 parent e73ca48 commit b666d20
Show file tree
Hide file tree
Showing 44 changed files with 556 additions and 161 deletions.
2 changes: 1 addition & 1 deletion docs/components/Circuit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</div>
<div class="mollitia-circuit-request">
<div>Simulate Request</div>
<div>Time: <input v-model.number="time" type="number"/></div>
<div>Time (in ms): <input v-model.number="time" type="number"/></div>
<div>
<button @click="triggerRequest" :disabled="disabled">Send Request</button>
<Toggle v-if="canFail" pre-label="Failure" post-label="Success" v-model="shouldSucceed"/>
Expand Down
4 changes: 2 additions & 2 deletions docs/components/global/playground/pg-cache.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export default {
};
},
methods: {
onCircuitEnd () {
this.$refs.ca1.onEnd();
onCircuitEnd (success) {
this.$refs.ca1.onEnd(success);
}
},
mounted () {
Expand Down
2 changes: 1 addition & 1 deletion docs/components/module/Bulkhead.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<div class="mollitia-module-bulkhead-config">
<div>Concurrent Requests: <input v-model.number="concurrentSize" @input="update" type="number"/></div>
<div>Queue Size: <input v-model.number="queueSize" @input="update" type="number"/></div>
<div>Max Queue Wait: <input v-model.number="maxQueueWait" @input="update" type="number"/></div>
<div>Max Queue Wait (in ms): <input v-model.number="maxQueueWait" @input="update" type="number"/></div>
</div>
<div class="mollitia-module-bulkhead-visual">
<div class="mollitia-module-bulkhead-visual-concurrent-container">
Expand Down
29 changes: 18 additions & 11 deletions docs/components/module/Cache.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
</div>
<div class="mollitia-module-cache-content">
<div class="mollitia-module-cache-config">
<div>TTL: <input v-model.number="ttl" @input="update" type="number"/></div>
<div>TTL (in ms): <input v-model.number="ttl" @input="update" type="number"/></div>
<div>Clear Interval (in ms): <input v-model.number="clearanceInterval" @input="update" type="number"/></div>
</div>
<div class="mollitia-module-cache-visual">
<div class="mollitia-module-cache-time">
Expand Down Expand Up @@ -33,6 +34,7 @@ export default {
return {
cache: null,
ttl: 10000,
clearanceInterval: 20000,
timePercent: 0,
percent: 0,
timeInterval: null,
Expand Down Expand Up @@ -62,6 +64,7 @@ export default {
methods: {
update () {
this.cache.ttl = this.ttl;
this.cache.cacheClearInterval = this.clearanceInterval;
},
onExecute () {
if (this.percent === 100) {
Expand All @@ -76,28 +79,32 @@ export default {
}
}, 100);
},
onEnd () {
onEnd (success) {
this.failed = false;
this.timePercent = 100;
clearInterval(this.timeInterval);
// Cache
if (!this.interval) {
this.cached = true;
this.percent = 0;
this.interval = setInterval(() => {
this.percent += (100 * 100 / this.ttl);
if (this.percent >= 100) {
this.cached = false;
clearInterval(this.interval);
this.interval = null;
}
}, 100);
if (success) {
// TODO if this is from cache, do not do that
this.cached = true;
this.interval = setInterval(() => {
this.percent += (100 * 100 / this.ttl);
if (this.percent >= 100) {
this.cached = false;
clearInterval(this.interval);
this.interval = null;
}
}, 100);
}
}
}
},
created () {
this.cache = new this.$mollitia.Cache({
ttl: this.ttl,
cacheClearInterval: this.clearanceInterval,
logger: {
debug: this.$parent.log
}
Expand Down
2 changes: 0 additions & 2 deletions docs/components/module/RateLimit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
<div class="mollitia-module-rate-limit">
<div class="mollitia-module-rate-limit-header">
<div>{{ name }}</div>

</div>

<div class="mollitia-module-rate-limit-content">
<div class="mollitia-module-rate-limit-config">
<div class="form-control">
Expand Down
6 changes: 5 additions & 1 deletion docs/components/module/Retry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<div class="mollitia-module-retry-content">
<div class="mollitia-module-retry-config">
<div>Attempts: <input v-model.number="retries" @input="update" type="number"/></div>
<div>Interval (in ms): <input v-model.number="retryInterval" @input="update" type="number"/></div>
</div>
<div class="mollitia-module-retry-visual">
<div v-for="i in attempts" :key="i" class="mollitia-module-retry-attempt">
Expand Down Expand Up @@ -35,6 +36,7 @@ export default {
return {
retry: null,
retries: 2,
retryInterval: 0,
index: 0,
interval: null,
requests: []
Expand All @@ -54,6 +56,7 @@ export default {
},
update () {
this.retry.attempts = this.retries;
this.retry.interval = this.retryInterval;
},
onExecute () {
this.index = 0;
Expand Down Expand Up @@ -89,7 +92,8 @@ export default {
created () {
this.requests = new Array(this.attempts).fill(0, 0, this.attempts);
this.retry = new this.$mollitia.Retry({
attempts: this.retries
attempts: this.retries,
interval: this.retryInterval
});
this.retry.on('execute', this.onExecute);
this.retry.on('retry', this.onRetry);
Expand Down
2 changes: 1 addition & 1 deletion docs/components/module/Timeout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<div class="mollitia-module-timeout-content">
<div class="mollitia-module-timeout-config">
<div>Delay: <input v-model.number="delay" @input="update" type="number"/></div>
<div>Delay (in ms): <input v-model.number="delay" @input="update" type="number"/></div>
</div>
<div class="mollitia-module-timeout-visual">
<div class="mollitia-module-timeout-percentage">
Expand Down
1 change: 0 additions & 1 deletion docs/components/module/breaker/Sliding.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<div class="mollitia-module-sliding-window-breaker-header">
<div>{{ name }}</div>
</div>

<div class="mollitia-module-sliding-window-breaker-content">
<div class="mollitia-module-sliding-window-breaker-config">
<div class="form-control">
Expand Down
24 changes: 13 additions & 11 deletions docs/content/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,22 @@ links:
path: /api/module/breaker/sliding/count
- title: Time Breaker
path: /api/module/breaker/sliding/time
- group: Modules
- group: Core Plugins
links:
- title: Prometheus
# TODO link to prometheus static doc
path: /api/plugin/prometheus
- group: Customization
links:
- title: Create a module
path: /api/create-module
- group: Plugins
links:
- title: Create a plugin
path: /api/create-plugin
- title: Prometheus
path: /api/plugin/prometheus
- group: Community
links:
- title: Modules
path: /community/modules
- title: Plugins
path: /community/plugins
# TODO add when possible
# - group: Community
# links:
# - title: Modules
# path: /community/modules
# - title: Plugins
# path: /community/plugins
---
69 changes: 68 additions & 1 deletion docs/content/api/circuit.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,72 @@
---
title: Mollitia - API - Circuit
---
# Circuit

Circuit
The `Circuit` is the container of your **Resilience** logic.

## Usage

``` javascript
// Imports the library
const { Circuit } = require('mollitia');
// Creates a circuit
const pgCircuit = new Circuit({
name: 'PostgreSQL Operations'
});
// Call operations
await circuit.fn(sqlRequest).execute('SELECT * FROM Mollitia;');
```

That is not really useful, as by default, the circuit just calls your method, with your arguments.

## Modules

Adding modules to your circuit will add logic to it, but be careful, **the module ordering have an importance!**
Let's see with an example:

``` javascript
// Imports needed components
const { Circuit, Retry, Timeout } = require('mollitia');
// Creates a Retry Module
const retry = new Retry({
attempts: 2, // Will retry two times
});
const timeout = new Timeout({
delay: 500, // Will timeout after 500ms
});
// Creates Circuits
const retryWithTimeout = new Circuit({
options: {
modules: [retry, timeout]
}
});
const timeoutRetries = new Circuit({
options: {
modules: [timeout, retry]
}
});
```

### Retry with Timeout

Here is what will happen with the first circuit:

``` javascript
retryWithTimeout.fn(failureAsync).execute('dummy', 1000) // Launches the failureAsync method, that will return "dummy", and will take 1000ms to complete
// Attempt #1: The function times out (1000 > 500) - Launches First Retry
// Attempt #2: The function times out (1000 > 500) - Launches Second Retry
// Attempt #3: The function times out (1000 > 500) - Fails with TimeoutError
```

### Timeout Retries

Here is what will happen with the second circuit:

``` javascript
timeoutRetries.fn(failureAsync).execute('dummy', 1000) // Exactly like before
// Attempt #1: The function times out (1000 > 500) - Fails with TimeoutError
```

Because the [Timeout](/api/module/timeout) module is set before the [Retry](/api/module/retry) module, the timeout is global for all attempts.
Therefore, the Circuit does have time to make a retry, it times out before.
43 changes: 42 additions & 1 deletion docs/content/api/create-module.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
---
title: Mollitia - API - Create a module
---
# Create a module

Create a module
Creating a new module is easy, you can extends the base **Module** class and use it like so:

``` javascript
// Imports the library
const { Circuit, Module } = require('mollitia');

// Creates a class
class UselessModule extends Module {
// Should implement the constructor, and call super(options)
constructor (options) {
super(options);
this.message = options.message;
}
// Should implement the execute method
async execute (circuit, promise, ...params) {
// circuit: Circuit being executed
// promise: The Circuit Function being used
// params[]: The list of parameters being used
console.info(`${circuit.name} - ${this.message}`); // That's some useful stuff
return promise(...params); // This just executes normally the method
}
}

// Let's use our new module
const circuit = new Circuit({
name: 'UselessCircuit',
options: {
modules: [
new UselessModule({
message: 'Hello World!'
})
]
}
});

// Execute the circuit
circuit.fn(() => { return; }).execute();

// Logs will be:
// UselessCircuit - Hello World!
```
20 changes: 19 additions & 1 deletion docs/content/api/create-plugin.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
---
title: Mollitia - API - Create a plugin
---
# Create a plugin

Create a plugin
Creating a plugin is similar as [creating a module](/api/create-module), you should implement the **Plugin** interface:

``` javascript
// Imports the library
const Mollitia = require('mollitia');

// Creates a class
class UselessPlugin implements Mollitia.Plugin {
// Called when a circuit is created
onCircuitCreate (circuit, options) {
// Feel free to modify the circuit behavior, and add properties to it
}
// Called when a module is created
onModuleCreate (module, options) {
// Feel free to modify the module behavior, and add properties to it
}
}
```
6 changes: 3 additions & 3 deletions docs/content/api/module/bulkhead.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ circuit.fn(myFunction).execute()

## Events

| Name | Description | Params |
|:-----------|:-------------------------------------|:-------------------|
| `execute` | Called when the module is executed. | `Mollitia.Circuit` |
| Name | Description | Params |
|:-----------|:-------------------------------------|:--------------- ---------------|
| `execute` | Called when the module is executed. | `Mollitia.Circuit` **circuit** |
25 changes: 17 additions & 8 deletions docs/content/api/module/cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Once you call a **function**, with some **parameters**, it will check if it has
> It is important to understand that the cache works by reference!<br/>
> That means that the cache is specificly referenced **for one function**, and **for the same parameters**.<br/>
Also, when a circuit fails and have an outdated cached response (ttl has been passed), the circuit will fire the request, and will respond with the new value if it succeeds, otherwise it will resolve with the cached response.

``` javascript
// Imports needed components
const { Circuit, Cache } = require('mollitia');
Expand All @@ -22,7 +24,8 @@ const circuit = new Circuit({
modules: [
// Creates a cache module
new Cache({
ttl: 60000 // A cached response will be kept for 1 minute
ttl: 60000, // A cached response will be considered as valid for 1 minute
cacheClearInterval: 900000 // A cached response will be kept for 15 minutes
})
]
}
Expand All @@ -46,17 +49,23 @@ await circuit.fn(myFirstFunction).execute(myObject);
// That won't return the cached result, as the function is different
await circuit.fn(mySecondFunction).execute(myObject);
// ... After 1 minute, the function is called again.
await circuit.fn(myFirstFunction).execute(myObject);
circuit.fn(myFirstFunction).execute(myObject)
.then(() => {
// If the request suceeds, it returns the result normally
// If not, the old cached response is returned
});
// After 15 minutes, the cache is cleared.
```

## Options

| Name | Description | Default |
|:-------|:------------------------------------------------------|:-----------|
| `ttl` | The amount of time before a cached result is cleared. | `Infinity` |
| Name | Description | Default |
|:----------------------|:---------------------------------------------------------------|:-----------|
| `ttl` | The amount of time before a cached result is considered valid. | `6000` |
| `cacheClearInterval` | The amount of time before the cache cleans itself up. | `900000` |

## Events

| Name | Description | Params |
|:-----------|:------------------------------------|:-------------------|
| `execute` | Called when the module is executed. | `Mollitia.Circuit` |
| Name | Description | Params |
|:-----------|:-------------------------------------|:--------------- ---------------|
| `execute` | Called when the module is executed. | `Mollitia.Circuit` **circuit** |
Loading

0 comments on commit b666d20

Please sign in to comment.