Skip to content

Commit

Permalink
GAPI-24676: add bulkhead module with playground
Browse files Browse the repository at this point in the history
  • Loading branch information
cadgerfeast committed Oct 28, 2020
1 parent 264e813 commit 8488ca4
Show file tree
Hide file tree
Showing 11 changed files with 383 additions and 17 deletions.
37 changes: 31 additions & 6 deletions docs/components/Circuit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<div>Simulate Request</div>
<div>Time: <input v-model.number="time" type="number"/></div>
<div>
<button @click="triggerSuccess" :disabled="active">Success</button>
<button @click="triggerFailure" :disabled="active">Failure</button>
<button @click="triggerSuccess" :disabled="disabled">Success</button>
<button @click="triggerFailure" :disabled="disabled">Failure</button>
</div>
</div>
<div ref="logs" class="mollitia-circuit-logs">
Expand Down Expand Up @@ -42,23 +42,45 @@ export default {
type: String,
default: 'Circuit'
},
initTime: {
type: Number,
default: 2000
},
modules: {
type: Array,
default: () => []
},
concurrent: {
type: Boolean,
default: false
},
successParams: {
type: Object,
default: () => { return {}; }
},
failureParams: {
type: Object,
default: () => { return {}; }
}
},
computed: {
disabled () {
return !this.concurrent && this.active;
}
},
data () {
return {
active: false,
circuit: null,
time: 2000,
time: this.initTime,
logs: ''
};
},
methods: {
triggerSuccess () {
this.$emit('start');
this.active = true;
this.circuit.fn(successAsync).execute('Normal Success', this.time)
this.circuit.fn(successAsync).execute('Normal Success', this.time, this.successParams)
.then((res) => {
this.logs += `<span>${res}</span><br/>`;
this.triggerUpdate();
Expand All @@ -72,8 +94,9 @@ export default {
});
},
triggerFailure () {
this.$emit('start');
this.active = true;
this.circuit.fn(failureAsync).execute('Normal Failure', this.time)
this.circuit.fn(failureAsync).execute('Normal Failure', this.time, this.failureParams)
.catch((err) => {
this.logs += `<span>${err.message}</span><br/>`;
this.triggerUpdate();
Expand All @@ -85,7 +108,9 @@ export default {
triggerUpdate () {
this.$emit('end');
setTimeout(() => {
this.$refs.logs.scrollTop = this.$refs.logs.scrollHeight;
if (this.$refs.logs) {
this.$refs.logs.scrollTop = this.$refs.logs.scrollHeight;
}
}, 1);
}
},
Expand Down
61 changes: 61 additions & 0 deletions docs/components/DataCircle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<div class="data-circle" :style="style" @mouseenter="showTooltip = true" @mouseleave="showTooltip = false">
<div v-show="tooltip && showTooltip" class="tooltip" :style="tooltipStyle">{{ tooltip }}</div>
</div>
</template>

<script>
export default {
name: 'DataCircle',
props: {
size: {
type: String,
default: '50px'
},
tooltip: {
type: String,
default: ''
},
color: {
type: String,
default: 'white'
}
},
data () {
return {
showTooltip: false
};
},
computed: {
style () {
return {
'width': this.size,
'height': this.size,
'background-color': this.color,
};
},
tooltipStyle () {
return {
'top': `calc(${this.size} + 5px`
};
}
}
}
</script>

<style lang="scss" scoped>
div.data-circle {
position: relative;
border-radius: 50%;
display: flex;
justify-content: center;
margin: 5px;
border: 2px solid white;
> div.tooltip {
position: absolute;
background-color: rgba(0, 0, 0, .5);
border-radius: 5px;
z-index: 1;
}
}
</style>
60 changes: 60 additions & 0 deletions docs/components/global/playground/pg-bulkhead.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<template>
<div class="mollitia-playground">
<Circuit ref="c1" @start="randomizeColor" :modules="modules" :concurrent="true" :success-params="successParams" :failure-params="failureParams" :init-time="4000">
<Bulkhead ref="b1"></Bulkhead>
</Circuit>
</div>
</template>

<script>
import Circuit from '../../Circuit';
import Bulkhead from '../../module/Bulkhead';
export default {
name: 'pg-bulkhead',
components: {
Circuit,
Bulkhead
},
data () {
return {
color: this.getRandomColor(),
modules: []
};
},
computed: {
successParams () {
return {
color: this.color
};
},
failureParams () {
return {
color: this.color
};
}
},
methods: {
randomizeColor () {
this.color = this.getRandomColor();
},
getRandomColor () {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
},
mounted () {
this.circuit = this.$refs.c1.circuit;
this.modules.push(this.$refs.b1.bulkhead);
}
}
</script>

<style lang="scss" scoped>
div.mollitia-playground {
height: 100%;
}
</style>
138 changes: 138 additions & 0 deletions docs/components/module/Bulkhead.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<template>
<div class="mollitia-module-bulkhead">
<div class="mollitia-module-bulkhead-header">
<div>{{ name }}</div>
</div>
<div class="mollitia-module-bulkhead-content">
<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>
<div class="mollitia-module-bulkhead-visual">
<div class="mollitia-module-bulkhead-visual-concurrent-container">
<div class="title">Concurrent:</div>
<DataCircle
v-for="(p, index) in concurrentBuffer"
:key="index"
:color="p.color"
:tooltip="p.tooltip"
:size="p.size">
</DataCircle>
</div>
<div class="mollitia-module-bulkhead-visual-queue-container">
<div class="title">Queue:</div>
<DataCircle
v-for="(p, index) in queueBuffer"
:key="index"
:color="p.color"
:tooltip="p.tooltip"
:size="p.size">
</DataCircle>
</div>
</div>
</div>
</div>
</template>

<script>
import DataCircle from '../DataCircle';
export default {
name: 'Bulkhead',
components: {
DataCircle
},
props: {
name: {
type: String,
default: 'Bulkhead'
}
},
data () {
return {
bulkhead: null,
concurrentSize: 6,
queueSize: 4,
maxQueueWait: 3000
};
},
computed: {
concurrentBuffer () {
const arr = [];
for (const promise of this.bulkhead.concurrentBuffer) {
arr.push({
size: '25px',
color: promise.params[2].color
});
}
return arr;
},
queueBuffer () {
const arr = [];
for (const promise of this.bulkhead.queueBuffer) {
arr.push({
size: '25px',
color: promise.params[2].color
});
}
return arr;
}
},
methods: {
update () {
this.bulkhead.concurrentSize = this.concurrentSize;
this.bulkhead.queueSize = this.queueSize;
this.bulkhead.maxQueueWait = this.maxQueueWait;
}
},
created () {
this.bulkhead = new this.$mollitia.Bulkhead({
concurrentSize: this.concurrentSize,
queueSize: this.queueSize,
maxQueueWait: this.maxQueueWait
});
}
}
</script>

<style lang="scss" scoped>
div.mollitia-module-bulkhead {
border: 1px solid var(--madoc-grey-5);
> div.mollitia-module-bulkhead-header {
padding: 10px;
border-bottom: 1px solid var(--madoc-grey-5);
}
> div.mollitia-module-bulkhead-content {
display: flex;
> div.mollitia-module-bulkhead-config {
padding: 10px;
border-right: 1px solid var(--madoc-grey-5);
}
> div.mollitia-module-bulkhead-visual {
flex-grow: 1;
> div.mollitia-module-bulkhead-visual-concurrent-container {
height: 50%;
width: 100%;
display: flex;
align-items: center;
> div.title {
align-items: center;
display: flex;
height: 100%;
}
}
> div.mollitia-module-bulkhead-visual-queue-container {
height: 50%;
width: 100%;
display: flex;
align-items: center;
> div.title {
align-items: center;
display: flex;
height: 100%;
}
}
}
}
}
</style>
1 change: 1 addition & 0 deletions docs/components/module/Retry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default {
this.retry.on('retry', this.onRetry);
},
destroyed () {
clearInterval(this.interval);
this.retry.off('execute', this.onExecute);
this.retry.off('retry', this.onRetry);
}
Expand Down
1 change: 1 addition & 0 deletions docs/components/module/Timeout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export default {
this.timeout.on('timeout', this.onTimeout);
},
destroyed () {
clearInterval(this.interval);
this.timeout.off('execute', this.onExecute);
this.timeout.off('timeout', this.onTimeout);
}
Expand Down
2 changes: 2 additions & 0 deletions docs/content/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ links:
path: /api/module/timeout
- title: Rate Limit
path: /api/module/rate-limit
- title: Bulkhead
path: /api/module/bulkhead
- title: Count Breaker
path: /api/module/breaker/sliding/count
- title: Time Breaker
Expand Down
10 changes: 10 additions & 0 deletions docs/content/api/module/bulkhead.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Mollitia - API - Module - Bulkhead
---
# Bulkhead

<pg-bulkhead></pg-bulkhead>

## Usage

TODO
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Cache } from './module/cache';
import { ConsecutiveBreaker } from './module/breaker/consecutive-breaker';
import { SlidingCountBreaker } from './module/breaker/sliding/count-breaker';
import { SlidingTimeBreaker } from './module/breaker/sliding/time-breaker';
import { Bulkhead, BulkheadOverloadError } from './module/bulkhead';
import { Bulkhead, BulkheadOverloadError, BulkheadQueueWaitError } from './module/bulkhead';

// Default Export
export {
Expand All @@ -30,6 +30,7 @@ export {
Cache,
Bulkhead,
BulkheadOverloadError,
BulkheadQueueWaitError,
// Plugin
use,
Plugin,
Expand Down
Loading

0 comments on commit 8488ca4

Please sign in to comment.