diff --git a/Makefile b/Makefile
index 3afb631..dc958e5 100644
--- a/Makefile
+++ b/Makefile
@@ -5,3 +5,6 @@ sample:
sample-clean:
@docker compose -f docker-compose.sample.yaml down
+
+benchmark:
+ dotnet run -c Release --project ./tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/Farfetch.LoadShedding.BenchmarkTests.csproj
diff --git a/data/grafana/dashboards/http_loadshedding.json b/data/grafana/dashboards/http_loadshedding.json
index 49f3475..1e8e0b8 100644
--- a/data/grafana/dashboards/http_loadshedding.json
+++ b/data/grafana/dashboards/http_loadshedding.json
@@ -83,6 +83,8 @@
},
"id": 55,
"options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
@@ -92,9 +94,10 @@
"values": false
},
"showThresholdLabels": false,
- "showThresholdMarkers": true
+ "showThresholdMarkers": true,
+ "sizing": "auto"
},
- "pluginVersion": "9.3.6",
+ "pluginVersion": "10.4.0",
"targets": [
{
"datasource": "$source",
@@ -154,6 +157,8 @@
},
"id": 59,
"options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
"orientation": "auto",
"reduceOptions": {
"calcs": [
@@ -163,9 +168,10 @@
"values": false
},
"showThresholdLabels": false,
- "showThresholdMarkers": true
+ "showThresholdMarkers": true,
+ "sizing": "auto"
},
- "pluginVersion": "9.3.6",
+ "pluginVersion": "10.4.0",
"targets": [
{
"datasource": "$source",
@@ -223,10 +229,12 @@
"fields": "",
"values": false
},
+ "showPercentChange": false,
"text": {},
- "textMode": "auto"
+ "textMode": "auto",
+ "wideLayout": true
},
- "pluginVersion": "9.3.6",
+ "pluginVersion": "10.4.0",
"targets": [
{
"datasource": "$source",
@@ -285,10 +293,12 @@
"fields": "",
"values": false
},
+ "showPercentChange": false,
"text": {},
- "textMode": "value"
+ "textMode": "value",
+ "wideLayout": true
},
- "pluginVersion": "9.3.6",
+ "pluginVersion": "10.4.0",
"targets": [
{
"datasource": "$source",
@@ -350,10 +360,12 @@
"fields": "",
"values": false
},
+ "showPercentChange": false,
"text": {},
- "textMode": "auto"
+ "textMode": "auto",
+ "wideLayout": true
},
- "pluginVersion": "9.3.6",
+ "pluginVersion": "10.4.0",
"targets": [
{
"datasource": "$source",
@@ -419,9 +431,11 @@
"fields": "",
"values": false
},
- "textMode": "auto"
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
},
- "pluginVersion": "9.3.6",
+ "pluginVersion": "10.4.0",
"targets": [
{
"datasource": "$source",
@@ -481,9 +495,11 @@
"fields": "",
"values": false
},
- "textMode": "auto"
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
},
- "pluginVersion": "9.3.6",
+ "pluginVersion": "10.4.0",
"targets": [
{
"datasource": "$source",
@@ -509,52 +525,132 @@
},
"id": 44,
"panels": [],
- "title": "Details",
+ "title": "Concurrency",
"type": "row"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "datasource": {
+ "type": "prometheus",
+ "uid": "$source"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "stepAfter",
+ "lineStyle": {
+ "fill": "solid"
+ },
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "normal"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "decimals": 0,
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "short"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "limit"
+ },
+ "properties": [
+ {
+ "id": "custom.lineStyle",
+ "value": {
+ "dash": [
+ 5,
+ 10
+ ],
+ "fill": "dash"
+ }
+ },
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "light-red",
+ "mode": "fixed"
+ }
+ },
+ {
+ "id": "custom.stacking",
+ "value": {
+ "group": "A",
+ "mode": "none"
+ }
+ },
+ {
+ "id": "custom.gradientMode",
+ "value": "opacity"
+ }
+ ]
+ }
+ ]
+ },
"gridPos": {
"h": 9,
- "w": 6,
+ "w": 12,
"x": 0,
"y": 8
},
- "hiddenSeries": false,
"id": 37,
- "legend": {
- "alignAsTable": true,
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
@@ -564,769 +660,980 @@
"format": "time_series",
"interval": "",
"intervalFactor": 1,
- "legendFormat": "Priority: {{priority}}",
+ "legendFormat": "{{priority}}",
"range": true,
"refId": "B"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "$source"
+ },
+ "editorMode": "code",
+ "expr": "sum(http_requests_concurrency_limit_total{job=\"$application\", instance=~\"$instance\"}) by (job)",
+ "hide": false,
+ "instant": false,
+ "legendFormat": "limit",
+ "range": true,
+ "refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
"title": "Concurrency Usage / Priority",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
"transformations": [
{
"id": "convertFieldType",
"options": {}
}
],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "$$hashKey": "object:703",
- "format": "short",
- "label": "",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "$$hashKey": "object:704",
- "format": "short",
- "logBase": 1,
- "show": true
- }
- ],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "percentunit"
+ },
+ "overrides": []
+ },
"gridPos": {
"h": 9,
- "w": 6,
- "x": 6,
+ "w": 12,
+ "x": 12,
"y": 8
},
- "hiddenSeries": false,
- "id": 38,
- "legend": {
- "alignAsTable": true,
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
+ "id": 58,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
"editorMode": "code",
"exemplar": true,
- "expr": "sum(http_requests_queue_items_total{job=\"$application\", instance=~\"$instance\"}) by (job,priority)",
+ "expr": "(sum(http_requests_concurrency_items_total{job=\"$application\", instance=~\"$instance\"}) by (job, instance)) / sum(http_requests_concurrency_limit_total{job=\"$application\", instance=~\"$instance\"}) by (job, instance)",
"format": "time_series",
"interval": "",
"intervalFactor": 1,
- "legendFormat": "Priority: {{priority}}",
+ "legendFormat": "{{instance}}",
"range": true,
"refId": "B"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "Queue Usage / Priority",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "short",
- "label": "",
- "logBase": 1,
- "min": "0",
- "show": true
- },
+ "title": "Concurrency Usage / Instance",
+ "transformations": [
{
- "format": "short",
- "logBase": 1,
- "show": true
+ "id": "convertFieldType",
+ "options": {
+ "conversions": [
+ {
+ "destinationType": "number",
+ "targetField": "Value"
+ }
+ ],
+ "fields": {}
+ }
}
],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "collapsed": false,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 17
+ },
+ "id": 64,
+ "panels": [],
+ "title": "Queue",
+ "type": "row"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "$source"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "stepAfter",
+ "lineStyle": {
+ "fill": "solid"
+ },
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "normal"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "short"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "limit"
+ },
+ "properties": [
+ {
+ "id": "custom.lineStyle",
+ "value": {
+ "dash": [
+ 5,
+ 10
+ ],
+ "fill": "dash"
+ }
+ },
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "light-red",
+ "mode": "fixed"
+ }
+ },
+ {
+ "id": "custom.gradientMode",
+ "value": "opacity"
+ },
+ {
+ "id": "custom.stacking",
+ "value": {
+ "group": "A",
+ "mode": "none"
+ }
+ }
+ ]
+ }
+ ]
+ },
"gridPos": {
"h": 9,
- "w": 6,
- "x": 12,
- "y": 8
+ "w": 12,
+ "x": 0,
+ "y": 18
},
- "hiddenSeries": false,
- "id": 31,
- "legend": {
- "alignAsTable": true,
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
+ "id": 38,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
"editorMode": "code",
"exemplar": true,
- "expr": "sum(rate(http_requests_task_processing_time_seconds_count{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (method, priority)",
+ "expr": "sum(http_requests_queue_items_total{job=\"$application\", instance=~\"$instance\"}) by (job, priority)",
"format": "time_series",
- "instant": false,
"interval": "",
"intervalFactor": 1,
- "legendFormat": "{{method}} {{priority}}",
+ "legendFormat": "{{priority}}",
+ "range": true,
+ "refId": "B"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "$source"
+ },
+ "editorMode": "code",
+ "expr": "sum(http_requests_queue_limit_total{job=\"$application\", instance=~\"$instance\"}) by (job)",
+ "hide": false,
+ "instant": false,
+ "legendFormat": "limit",
+ "range": true,
"refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "Task Execution / Second (Success)",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
+ "title": "Queue Usage / Priority",
"transformations": [
{
"id": "convertFieldType",
"options": {}
}
],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "reqps",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "format": "short",
- "logBase": 1,
- "min": "0",
- "show": true
- }
- ],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
"gridPos": {
"h": 9,
- "w": 6,
- "x": 18,
- "y": 8
+ "w": 4,
+ "x": 12,
+ "y": 18
},
- "hiddenSeries": false,
- "id": 58,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
+ "id": 35,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [
+ "mean",
+ "max",
+ "min"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
- "datasource": "$source",
+ "datasource": {
+ "uid": "$source"
+ },
"editorMode": "code",
- "exemplar": true,
- "expr": "(sum(http_requests_concurrency_items_total{job=\"$application\", instance=~\"$instance\"}) by (job, instance)) / sum(http_requests_concurrency_limit_total{job=\"$application\", instance=~\"$instance\"}) by (job, instance)",
+ "expr": "histogram_quantile(0.5, sum(rate(http_requests_queue_time_seconds_bucket{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (le, priority))",
"format": "time_series",
- "interval": "",
"intervalFactor": 1,
- "legendFormat": "{{instance}}",
+ "legendFormat": "{{priority}}",
"range": true,
- "refId": "B"
+ "refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "Concurrency Usage / Instance",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "percentunit",
- "label": "",
- "logBase": 1,
- "min": "0",
- "show": true
- },
+ "title": "Queue Time P50",
+ "transformations": [
{
- "format": "short",
- "logBase": 1,
- "show": true
- }
- ],
- "yaxis": {
- "align": false
- }
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
- "gridPos": {
- "h": 9,
- "w": 6,
- "x": 0,
- "y": 17
+ "id": "convertFieldType",
+ "options": {
+ "conversions": [
+ {
+ "destinationType": "number",
+ "targetField": "critical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "noncritical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "normal"
+ }
+ ],
+ "fields": {}
+ }
+ }
+ ],
+ "type": "timeseries"
+ },
+ {
+ "datasource": "$source",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 9,
+ "w": 4,
+ "x": 16,
+ "y": 18
},
- "hiddenSeries": false,
- "id": 57,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
+ "id": 63,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [
+ "mean",
+ "max",
+ "min"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
- {
- "datasource": "$source",
- "editorMode": "code",
- "exemplar": true,
- "expr": "sum(http_requests_concurrency_limit_total{job=\"$application\", instance=~\"$instance\"}) by (job)",
- "format": "time_series",
- "interval": "",
- "intervalFactor": 1,
- "legendFormat": "Limit",
- "range": true,
- "refId": "A"
- },
{
"datasource": {
"uid": "$source"
},
"editorMode": "code",
- "exemplar": true,
- "expr": "sum(http_requests_concurrency_items_total{job=\"$application\", instance=~\"$instance\"}) by (job)",
+ "expr": "histogram_quantile(0.90, sum(rate(http_requests_queue_time_seconds_bucket{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (le, priority))",
"format": "time_series",
- "interval": "",
"intervalFactor": 1,
- "legendFormat": "Usage",
+ "legendFormat": "{{priority}}",
"range": true,
- "refId": "B"
+ "refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "Concurrency Usage Total",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "short",
- "label": "",
- "logBase": 1,
- "show": true
- },
+ "title": "Queue Time P90",
+ "transformations": [
{
- "format": "short",
- "logBase": 1,
- "show": true
+ "id": "convertFieldType",
+ "options": {
+ "conversions": [
+ {
+ "destinationType": "number",
+ "targetField": "critical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "noncritical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "normal"
+ }
+ ],
+ "fields": {}
+ }
}
],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
"gridPos": {
"h": 9,
- "w": 6,
- "x": 6,
- "y": 17
+ "w": 4,
+ "x": 20,
+ "y": 18
},
- "hiddenSeries": false,
- "id": 30,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
+ "id": 39,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [
+ "mean",
+ "max",
+ "min"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
- {
- "datasource": "$source",
- "editorMode": "code",
- "exemplar": true,
- "expr": "sum(http_requests_queue_limit_total{job=\"$application\", instance=~\"$instance\"}) by (job)",
- "format": "time_series",
- "interval": "",
- "intervalFactor": 1,
- "legendFormat": "Limit",
- "range": true,
- "refId": "A"
- },
{
"datasource": {
"uid": "$source"
},
"editorMode": "code",
- "exemplar": true,
- "expr": "sum(http_requests_queue_items_total{job=\"$application\", instance=~\"$instance\"}) by (job)",
+ "expr": "histogram_quantile(0.99, sum(rate(http_requests_queue_time_seconds_bucket{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (le, priority))",
"format": "time_series",
- "interval": "",
"intervalFactor": 1,
- "legendFormat": "Usage",
+ "legendFormat": "Priority {{priority}}",
"range": true,
- "refId": "B"
+ "refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "Queue Usage Total",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "short",
- "label": "",
- "logBase": 1,
- "show": true
- },
+ "title": "Queue Time P99",
+ "transformations": [
{
- "format": "short",
- "logBase": 1,
- "show": true
+ "id": "convertFieldType",
+ "options": {
+ "conversions": [
+ {
+ "destinationType": "number",
+ "targetField": "Priority critical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "Priority noncritical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "Priority normal"
+ }
+ ],
+ "fields": {}
+ }
}
],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
+ },
+ {
+ "collapsed": false,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 27
+ },
+ "id": 42,
+ "panels": [],
+ "title": "Execution",
+ "type": "row"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "reqps"
+ },
+ "overrides": []
+ },
"gridPos": {
"h": 9,
"w": 6,
- "x": 12,
- "y": 17
+ "x": 0,
+ "y": 28
},
- "hiddenSeries": false,
- "id": 2,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
+ "id": 31,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
"editorMode": "code",
"exemplar": true,
- "expr": "sum(rate(http_requests_rejected_total{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (priority, method)",
+ "expr": "sum(rate(http_requests_task_processing_time_seconds_count{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (method, priority)",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
- "legendFormat": "{{method}} - {{priority}}",
+ "legendFormat": "{{method}} {{priority}}",
"refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "Rejection Rate / Priority",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
+ "title": "Task Execution / Second (Success)",
"transformations": [
{
"id": "convertFieldType",
"options": {}
}
],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "reqps",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "format": "short",
- "logBase": 1,
- "show": true
- }
- ],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "reqps"
+ },
+ "overrides": []
+ },
"gridPos": {
"h": 9,
"w": 6,
- "x": 18,
- "y": 17
+ "x": 6,
+ "y": 28
},
- "hiddenSeries": false,
- "id": 32,
- "legend": {
- "alignAsTable": false,
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null",
+ "id": 2,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
"editorMode": "code",
"exemplar": true,
- "expr": "sum(rate(process_cpu_seconds_total{job=\"$application\", instance=~\"$instance\"}[30s]) * 100) by (instance)",
+ "expr": "sum(rate(http_requests_rejected_total{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (priority, method)",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
- "legendFormat": "{{instance}}",
+ "legendFormat": "{{method}} - {{priority}}",
"refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "CPU",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "percent",
- "logBase": 1,
- "show": true
- },
+ "title": "Rejection Rate / Priority",
+ "transformations": [
{
- "format": "short",
- "logBase": 1,
- "show": true
+ "id": "convertFieldType",
+ "options": {}
}
],
- "yaxis": {
- "align": false
- }
- },
- {
- "collapsed": false,
- "gridPos": {
- "h": 1,
- "w": 24,
- "x": 0,
- "y": 26
- },
- "id": 42,
- "panels": [],
- "title": "Latencies",
- "type": "row"
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
"fieldConfig": {
"defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
"unit": "s"
},
"overrides": []
},
- "fill": 1,
- "fillGradient": 0,
"gridPos": {
"h": 9,
"w": 4,
- "x": 0,
- "y": 27
+ "x": 12,
+ "y": 28
},
- "hiddenSeries": false,
"id": 62,
- "legend": {
- "alignAsTable": true,
- "avg": true,
- "current": false,
- "hideEmpty": false,
- "max": true,
- "min": true,
- "rightSide": false,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [
+ "mean",
+ "max",
+ "min"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
@@ -1341,14 +1648,7 @@
"refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
"title": "Task Execution Time - P50",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
"transformations": [
{
"id": "convertFieldType",
@@ -1356,81 +1656,106 @@
"conversions": [
{
"destinationType": "number",
- "targetField": "Value"
- }
- ],
- "fields": {}
- }
- }
- ],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "s",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "format": "short",
- "label": "",
- "logBase": 1,
- "min": "0",
- "show": true
+ "targetField": " critical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": " noncritical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": " normal"
+ }
+ ],
+ "fields": {}
+ }
}
],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
"gridPos": {
"h": 9,
"w": 4,
- "x": 4,
- "y": 27
+ "x": 16,
+ "y": 28
},
- "hiddenSeries": false,
"id": 40,
- "legend": {
- "alignAsTable": true,
- "avg": true,
- "current": false,
- "max": true,
- "min": true,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [
+ "mean",
+ "max",
+ "min"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
@@ -1445,14 +1770,7 @@
"refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
"title": "Task Execution Time - P90",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
"transformations": [
{
"id": "convertFieldType",
@@ -1460,79 +1778,105 @@
"conversions": [
{
"destinationType": "number",
- "targetField": "Value"
+ "targetField": "critical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "noncritical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": "normal"
}
],
"fields": {}
}
}
],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "s",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "format": "short",
- "logBase": 1,
- "show": true
- }
- ],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "s"
+ },
+ "overrides": []
+ },
"gridPos": {
"h": 9,
"w": 4,
- "x": 8,
- "y": 27
+ "x": 20,
+ "y": 28
},
- "hiddenSeries": false,
"id": 45,
- "legend": {
- "alignAsTable": true,
- "avg": true,
- "current": false,
- "max": true,
- "min": true,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [
+ "mean",
+ "max",
+ "min"
+ ],
+ "displayMode": "table",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
"datasource": "$source",
@@ -1547,331 +1891,156 @@
"refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
"title": "Task Execution Time - P99",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
"transformations": [
{
"id": "convertFieldType",
- "options": {}
- }
- ],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "s",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "format": "short",
- "logBase": 1,
- "show": true
+ "options": {
+ "conversions": [
+ {
+ "destinationType": "number",
+ "targetField": " critical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": " noncritical"
+ },
+ {
+ "destinationType": "number",
+ "targetField": " normal"
+ }
+ ],
+ "fields": {}
+ }
}
],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "collapsed": false,
"gridPos": {
- "h": 9,
- "w": 4,
- "x": 12,
- "y": 27
- },
- "hiddenSeries": false,
- "id": 35,
- "legend": {
- "alignAsTable": true,
- "avg": true,
- "current": false,
- "max": true,
- "min": true,
- "rightSide": false,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
- "options": {
- "alertThreshold": true
- },
- "paceLength": 10,
- "percentage": false,
- "pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
- "targets": [
- {
- "datasource": {
- "uid": "$source"
- },
- "editorMode": "code",
- "expr": "histogram_quantile(0.5, sum(rate(http_requests_queue_time_seconds_bucket{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (le, priority))",
- "format": "time_series",
- "intervalFactor": 1,
- "legendFormat": "{{priority}}",
- "range": true,
- "refId": "A"
- }
- ],
- "thresholds": [],
- "timeRegions": [],
- "title": "Queue Time P50",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
- "transformations": [
- {
- "id": "convertFieldType",
- "options": {}
- }
- ],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 37
},
- "yaxes": [
- {
- "format": "s",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "format": "short",
- "logBase": 1,
- "show": true
- }
- ],
- "yaxis": {
- "align": false
- }
+ "id": 65,
+ "panels": [],
+ "title": "Resources",
+ "type": "row"
},
{
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
"datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
- "gridPos": {
- "h": 9,
- "w": 4,
- "x": 16,
- "y": 27
- },
- "hiddenSeries": false,
- "id": 63,
- "legend": {
- "alignAsTable": true,
- "avg": true,
- "current": false,
- "max": true,
- "min": true,
- "rightSide": false,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
- "options": {
- "alertThreshold": true
- },
- "paceLength": 10,
- "percentage": false,
- "pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
- "targets": [
- {
- "datasource": {
- "uid": "$source"
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
},
- "editorMode": "code",
- "expr": "histogram_quantile(0.90, sum(rate(http_requests_queue_time_seconds_bucket{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (le, priority))",
- "format": "time_series",
- "intervalFactor": 1,
- "legendFormat": "{{priority}}",
- "range": true,
- "refId": "A"
- }
- ],
- "thresholds": [],
- "timeRegions": [],
- "title": "Queue Time P90",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
- "transformations": [
- {
- "id": "convertFieldType",
- "options": {}
- }
- ],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "s",
- "logBase": 1,
- "min": "0",
- "show": true
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "percent"
},
- {
- "format": "short",
- "logBase": 1,
- "show": true
- }
- ],
- "yaxis": {
- "align": false
- }
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "$source",
- "fill": 1,
- "fillGradient": 0,
+ "overrides": []
+ },
"gridPos": {
"h": 9,
- "w": 4,
- "x": 20,
- "y": 27
+ "w": 6,
+ "x": 0,
+ "y": 38
},
- "hiddenSeries": false,
- "id": 39,
- "legend": {
- "alignAsTable": true,
- "avg": true,
- "current": false,
- "max": true,
- "min": true,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
+ "id": 32,
"options": {
- "alertThreshold": true
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "none"
+ }
},
- "paceLength": 10,
- "percentage": false,
"pluginVersion": "9.3.6",
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
"targets": [
{
- "datasource": {
- "uid": "$source"
- },
+ "datasource": "$source",
"editorMode": "code",
- "expr": "histogram_quantile(0.99, sum(rate(http_requests_queue_time_seconds_bucket{job=\"$application\", instance=~\"$instance\"}[$__rate_interval])) by (le, priority))",
+ "exemplar": true,
+ "expr": "sum(rate(process_cpu_seconds_total{job=\"$application\", instance=~\"$instance\"}[30s]) * 100) by (instance)",
"format": "time_series",
+ "instant": false,
+ "interval": "",
"intervalFactor": 1,
- "legendFormat": "Priority {{priority}}",
- "range": true,
+ "legendFormat": "{{instance}}",
"refId": "A"
}
],
- "thresholds": [],
- "timeRegions": [],
- "title": "Queue Time P99",
- "tooltip": {
- "shared": true,
- "sort": 0,
- "value_type": "individual"
- },
+ "title": "CPU",
"transformations": [
{
"id": "convertFieldType",
- "options": {}
- }
- ],
- "type": "graph",
- "xaxis": {
- "mode": "time",
- "show": true,
- "values": []
- },
- "yaxes": [
- {
- "format": "s",
- "logBase": 1,
- "min": "0",
- "show": true
- },
- {
- "format": "short",
- "logBase": 1,
- "show": true
+ "options": {
+ "conversions": [
+ {
+ "destinationType": "number",
+ "targetField": "Value"
+ }
+ ],
+ "fields": {}
+ }
}
],
- "yaxis": {
- "align": false
- }
+ "type": "timeseries"
}
],
"refresh": "1m",
- "schemaVersion": 37,
- "style": "dark",
+ "schemaVersion": 39,
"tags": [
"kubernetes"
],
@@ -1880,8 +2049,8 @@
{
"current": {
"selected": false,
- "text": "LoadSheddingMetrics",
- "value": "LoadSheddingMetrics"
+ "text": "",
+ "value": ""
},
"hide": 0,
"includeAll": false,
@@ -1901,7 +2070,9 @@
"text": "",
"value": ""
},
- "datasource": "$source",
+ "datasource": {
+ "uid": "$source"
+ },
"definition": "label_values(http_requests_concurrency_limit_total,job)",
"hide": 0,
"includeAll": false,
@@ -1931,15 +2102,17 @@
"$__all"
]
},
- "datasource": "$source",
- "definition": "label_values(http_requests_concurrency_limit_total,instance)",
+ "datasource": {
+ "uid": "$source"
+ },
+ "definition": "label_values(http_requests_concurrency_limit_total{job=\"$application\"},instance)",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "instance",
"options": [],
"query": {
- "query": "label_values(http_requests_concurrency_limit_total,instance)",
+ "query": "label_values(http_requests_concurrency_limit_total{job=\"$application\"},instance)",
"refId": "StandardVariableQuery"
},
"refresh": 2,
@@ -1954,7 +2127,7 @@
]
},
"time": {
- "from": "now-5m",
+ "from": "now-15m",
"to": "now"
},
"timepicker": {
@@ -1982,6 +2155,6 @@
"timezone": "utc",
"title": "http_loadshedding",
"uid": "http_loadshedding",
- "version": 1,
+ "version": 2,
"weekStart": ""
-}
\ No newline at end of file
+}
diff --git a/src/Farfetch.LoadShedding/Events/Args/ItemDequeuedEventArgs.cs b/src/Farfetch.LoadShedding/Events/Args/ItemDequeuedEventArgs.cs
index d632a19..6b04d52 100644
--- a/src/Farfetch.LoadShedding/Events/Args/ItemDequeuedEventArgs.cs
+++ b/src/Farfetch.LoadShedding/Events/Args/ItemDequeuedEventArgs.cs
@@ -6,29 +6,17 @@ namespace Farfetch.LoadShedding.Events.Args
///
/// Event args for the task dequeued event.
///
- public class ItemDequeuedEventArgs : ItemEventArgs
+ public class ItemDequeuedEventArgs : TaskQueueEventArgs
{
- internal ItemDequeuedEventArgs(Priority priority, TimeSpan queueTime, int queueLimit, int queueCount)
- : base(priority)
+ internal ItemDequeuedEventArgs(Priority priority, TimeSpan queueTime, IReadOnlyCounter queueCounter)
+ : base(priority, queueCounter)
{
this.QueueTime = queueTime;
- this.QueueLimit = queueLimit;
- this.QueueCount = queueCount;
}
///
/// Gets the time waiting in the queue.
///
public TimeSpan QueueTime { get; }
-
- ///
- /// Gets the maximum number of items in the queue.
- ///
- public int QueueLimit { get; }
-
- ///
- /// Gets the current number of items in the queue.
- ///
- public int QueueCount { get; }
}
}
diff --git a/src/Farfetch.LoadShedding/Events/Args/ItemEnqueuedEventArgs.cs b/src/Farfetch.LoadShedding/Events/Args/ItemEnqueuedEventArgs.cs
index 95ea4b2..afea2a6 100644
--- a/src/Farfetch.LoadShedding/Events/Args/ItemEnqueuedEventArgs.cs
+++ b/src/Farfetch.LoadShedding/Events/Args/ItemEnqueuedEventArgs.cs
@@ -5,23 +5,11 @@ namespace Farfetch.LoadShedding.Events.Args
///
/// Event args for the task enqueued event.
///
- public class ItemEnqueuedEventArgs : ItemEventArgs
+ public class ItemEnqueuedEventArgs : TaskQueueEventArgs
{
- internal ItemEnqueuedEventArgs(Priority priority, int queueLimit, int queueCount)
- : base(priority)
+ internal ItemEnqueuedEventArgs(Priority priority, IReadOnlyCounter queueCounter)
+ : base(priority, queueCounter)
{
- this.QueueLimit = queueLimit;
- this.QueueCount = queueCount;
}
-
- ///
- /// Gets the maximum number of items in the queue.
- ///
- public int QueueLimit { get; }
-
- ///
- /// Gets the current number of items in the queue.
- ///
- public int QueueCount { get; }
}
}
diff --git a/src/Farfetch.LoadShedding/Events/Args/ItemProcessedEventArgs.cs b/src/Farfetch.LoadShedding/Events/Args/ItemProcessedEventArgs.cs
index 0b3008a..470f0f3 100644
--- a/src/Farfetch.LoadShedding/Events/Args/ItemProcessedEventArgs.cs
+++ b/src/Farfetch.LoadShedding/Events/Args/ItemProcessedEventArgs.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using Farfetch.LoadShedding.Tasks;
namespace Farfetch.LoadShedding.Events.Args
@@ -6,29 +6,17 @@ namespace Farfetch.LoadShedding.Events.Args
///
/// Event args for task processed event.
///
- public class ItemProcessedEventArgs : ItemEventArgs
+ public class ItemProcessedEventArgs : TaskItemEventArgs
{
- internal ItemProcessedEventArgs(Priority priority, TimeSpan processingTime, int concurrencyLimit, int concurrencyCount)
- : base(priority)
+ internal ItemProcessedEventArgs(Priority priority, TimeSpan processingTime, IReadOnlyCounter concurrencyCounter)
+ : base(priority, concurrencyCounter)
{
this.ProcessingTime = processingTime;
- this.ConcurrencyLimit = concurrencyLimit;
- this.ConcurrencyCount = concurrencyCount;
}
///
/// Gets time spent to process the task.
///
public TimeSpan ProcessingTime { get; }
-
- ///
- /// Gets the current concurrency limit.
- ///
- public int ConcurrencyLimit { get; }
-
- ///
- /// Gets the current concurrency items count.
- ///
- public int ConcurrencyCount { get; }
}
}
diff --git a/src/Farfetch.LoadShedding/Events/Args/ItemProcessingEventArgs.cs b/src/Farfetch.LoadShedding/Events/Args/ItemProcessingEventArgs.cs
index e8238d5..3e41c11 100644
--- a/src/Farfetch.LoadShedding/Events/Args/ItemProcessingEventArgs.cs
+++ b/src/Farfetch.LoadShedding/Events/Args/ItemProcessingEventArgs.cs
@@ -1,27 +1,15 @@
-using Farfetch.LoadShedding.Tasks;
+using Farfetch.LoadShedding.Tasks;
namespace Farfetch.LoadShedding.Events.Args
{
///
- /// Event args for task procssing event.
+ /// Event args for task processing event.
///
- public class ItemProcessingEventArgs : ItemEventArgs
+ public class ItemProcessingEventArgs : TaskItemEventArgs
{
- internal ItemProcessingEventArgs(Priority priority, int concurrencyLimit, int concurrencyCount)
- : base(priority)
+ internal ItemProcessingEventArgs(Priority priority, IReadOnlyCounter concurrencyCounter)
+ : base(priority, concurrencyCounter)
{
- this.ConcurrencyLimit = concurrencyLimit;
- this.ConcurrencyCount = concurrencyCount;
}
-
- ///
- /// Gets the current concurrency limit.
- ///
- public int ConcurrencyLimit { get; }
-
- ///
- /// Gets the current concurrency items count.
- ///
- public int ConcurrencyCount { get; }
}
}
diff --git a/src/Farfetch.LoadShedding/Events/Args/TaskItemEventArgs.cs b/src/Farfetch.LoadShedding/Events/Args/TaskItemEventArgs.cs
new file mode 100644
index 0000000..6254cc4
--- /dev/null
+++ b/src/Farfetch.LoadShedding/Events/Args/TaskItemEventArgs.cs
@@ -0,0 +1,28 @@
+using Farfetch.LoadShedding.Tasks;
+
+namespace Farfetch.LoadShedding.Events.Args
+{
+ ///
+ /// Event args for task item event.
+ ///
+ public class TaskItemEventArgs : ItemEventArgs
+ {
+ private readonly IReadOnlyCounter _concurrencyCounter;
+
+ internal TaskItemEventArgs(Priority priority, IReadOnlyCounter concurrencyCounter)
+ : base(priority)
+ {
+ _concurrencyCounter = concurrencyCounter;
+ }
+
+ ///
+ /// Gets the current concurrency limit.
+ ///
+ public int ConcurrencyLimit => _concurrencyCounter.Limit;
+
+ ///
+ /// Gets the current concurrency items count.
+ ///
+ public int ConcurrencyCount => _concurrencyCounter.Count;
+ }
+}
diff --git a/src/Farfetch.LoadShedding/Events/Args/TaskQueueEventArgs.cs b/src/Farfetch.LoadShedding/Events/Args/TaskQueueEventArgs.cs
new file mode 100644
index 0000000..ee9f56c
--- /dev/null
+++ b/src/Farfetch.LoadShedding/Events/Args/TaskQueueEventArgs.cs
@@ -0,0 +1,28 @@
+using Farfetch.LoadShedding.Tasks;
+
+namespace Farfetch.LoadShedding.Events.Args
+{
+ ///
+ /// Event args for the task queue event.
+ ///
+ public class TaskQueueEventArgs : ItemEventArgs
+ {
+ private readonly IReadOnlyCounter _queueCounter;
+
+ internal TaskQueueEventArgs(Priority priority, IReadOnlyCounter queueCounter)
+ : base(priority)
+ {
+ this._queueCounter = queueCounter;
+ }
+
+ ///
+ /// Gets the maximum number of items in the queue.
+ ///
+ public int QueueLimit => _queueCounter.Limit;
+
+ ///
+ /// Gets the current number of items in the queue.
+ ///
+ public int QueueCount => _queueCounter.Count;
+ }
+}
diff --git a/src/Farfetch.LoadShedding/Tasks/ConcurrentCounter.cs b/src/Farfetch.LoadShedding/Tasks/ConcurrentCounter.cs
index 1d3cf82..764c74f 100644
--- a/src/Farfetch.LoadShedding/Tasks/ConcurrentCounter.cs
+++ b/src/Farfetch.LoadShedding/Tasks/ConcurrentCounter.cs
@@ -1,8 +1,8 @@
-namespace Farfetch.LoadShedding.Tasks
+namespace Farfetch.LoadShedding.Tasks
{
- internal class ConcurrentCounter
+ internal class ConcurrentCounter : IReadOnlyCounter
{
- private readonly object _locker = new object();
+ private readonly object _locker = new();
private int _count = 0;
@@ -64,10 +64,7 @@ public int Decrement()
{
lock (this._locker)
{
- if (this._count > 0)
- {
- this._count--;
- }
+ this._count--;
return this._count;
}
diff --git a/src/Farfetch.LoadShedding/Tasks/IReadOnlyCounter.cs b/src/Farfetch.LoadShedding/Tasks/IReadOnlyCounter.cs
new file mode 100644
index 0000000..87e285e
--- /dev/null
+++ b/src/Farfetch.LoadShedding/Tasks/IReadOnlyCounter.cs
@@ -0,0 +1,9 @@
+namespace Farfetch.LoadShedding.Tasks
+{
+ internal interface IReadOnlyCounter
+ {
+ int Count { get; }
+
+ int Limit { get; }
+ }
+}
diff --git a/src/Farfetch.LoadShedding/Tasks/Priority.cs b/src/Farfetch.LoadShedding/Tasks/Priority.cs
index 57d9f1b..9e1e60d 100644
--- a/src/Farfetch.LoadShedding/Tasks/Priority.cs
+++ b/src/Farfetch.LoadShedding/Tasks/Priority.cs
@@ -6,17 +6,17 @@ namespace Farfetch.LoadShedding.Tasks
public enum Priority
{
///
- /// Priority as critical.
+ /// Priority as Critical.
///
Critical = 0,
///
- /// Priority as normal.
+ /// Priority as Normal.
///
Normal = 1,
///
- /// Priority as critical.
+ /// Priority as Non Critical.
///
NonCritical = 2,
}
diff --git a/src/Farfetch.LoadShedding/Tasks/TaskManager.cs b/src/Farfetch.LoadShedding/Tasks/TaskManager.cs
index ac13252..438405e 100644
--- a/src/Farfetch.LoadShedding/Tasks/TaskManager.cs
+++ b/src/Farfetch.LoadShedding/Tasks/TaskManager.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Threading;
using System.Threading.Tasks;
using Farfetch.LoadShedding.Constants;
@@ -12,7 +12,7 @@ internal class TaskManager : ITaskManager
{
private readonly TaskQueue _taskQueue;
- private readonly ConcurrentCounter _counter = new ConcurrentCounter();
+ private readonly ConcurrentCounter _counter = new();
private readonly int _queueTimeout;
private readonly ILoadSheddingEvents _events;
@@ -30,8 +30,8 @@ public TaskManager(
this._taskQueue = new TaskQueue(maxQueueSize)
{
- OnItemEnqueued = (count, item) => this.NotifyItemEnqueued(count, item),
- OnItemDequeued = (count, item) => this.NotifyItemDequeued(count, item),
+ OnItemEnqueued = this.NotifyItemEnqueued,
+ OnItemDequeued = this.NotifyItemDequeued,
};
this._events?.ConcurrencyLimitChanged?.Raise(new LimitChangedEventArgs(this._counter.Limit));
@@ -86,11 +86,11 @@ public async Task AcquireAsync(Priority priority, CancellationToken ca
{
var item = this.CreateTask(priority);
- if (this._counter.TryIncrement(out var currentCount))
+ if (this._counter.TryIncrement(out var _))
{
item.Process();
- this.NotifyItemProcessing(item, currentCount);
+ this.NotifyItemProcessing(item);
return item;
}
@@ -124,7 +124,8 @@ await item
break;
}
- this.NotifyItemProcessing(item, this._counter.Increment());
+ this._counter.Increment();
+ this.NotifyItemProcessing(item);
return item;
}
@@ -136,10 +137,9 @@ private TaskItem CreateTask(Priority priority)
item.OnCompleted = () =>
{
var count = this._counter.Decrement();
-
var processNext = count < this._counter.Limit;
- this.NotifyItemProcessed(item, count);
+ this.NotifyItemProcessed(item);
if (processNext)
{
@@ -155,32 +155,28 @@ private void NotifyItemRejected(TaskItem item, string reason)
item.Priority,
reason));
- private void NotifyItemProcessed(TaskItem item, int count)
+ private void NotifyItemProcessed(TaskItem item)
=> this._events?.ItemProcessed?.Raise(new ItemProcessedEventArgs(
item.Priority,
item.ProcessingTime,
- this.ConcurrencyLimit,
- count));
+ this._counter));
- private void NotifyItemProcessing(TaskItem item, int count)
+ private void NotifyItemProcessing(TaskItem item)
=> this._events?.ItemProcessing?.Raise(new ItemProcessingEventArgs(
item.Priority,
- this.ConcurrencyLimit,
- count));
+ this._counter));
private void NotifyConcurrencyLimitChanged()
=> this._events?.ConcurrencyLimitChanged?.Raise(new LimitChangedEventArgs(this._counter.Limit));
- private void NotifyItemDequeued(int count, TaskItem item) => this._events?.ItemDequeued?.Raise(new ItemDequeuedEventArgs(
+ private void NotifyItemDequeued(TaskItem item) => this._events?.ItemDequeued?.Raise(new ItemDequeuedEventArgs(
item.Priority,
item.WaitingTime,
- this._taskQueue.Limit,
- count));
+ this._taskQueue));
- private void NotifyItemEnqueued(int count, TaskItem item) => this._events?.ItemEnqueued?.Raise(new ItemEnqueuedEventArgs(
+ private void NotifyItemEnqueued(TaskItem item) => this._events?.ItemEnqueued?.Raise(new ItemEnqueuedEventArgs(
item.Priority,
- this._taskQueue.Limit,
- count));
+ this._taskQueue));
private void ProcessPendingTasks()
{
diff --git a/src/Farfetch.LoadShedding/Tasks/TaskQueue.cs b/src/Farfetch.LoadShedding/Tasks/TaskQueue.cs
index 2f113ce..6961492 100644
--- a/src/Farfetch.LoadShedding/Tasks/TaskQueue.cs
+++ b/src/Farfetch.LoadShedding/Tasks/TaskQueue.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -7,16 +6,11 @@
namespace Farfetch.LoadShedding.Tasks
{
- internal class TaskQueue
+ internal class TaskQueue : IReadOnlyCounter
{
- private readonly ConcurrentCounter _counter = new ConcurrentCounter();
+ private readonly ConcurrentCounter _counter = new();
- private readonly IDictionary _queues = new SortedDictionary()
- {
- [Priority.Critical] = new TaskItemList(),
- [Priority.Normal] = new TaskItemList(),
- [Priority.NonCritical] = new TaskItemList(),
- };
+ private readonly TaskItemList[] _queues = new TaskItemList[3] { new(), new(), new() };
public TaskQueue(int limit)
{
@@ -31,9 +25,9 @@ public int Limit
set => this._counter.Limit = value;
}
- public Action OnItemEnqueued { get; set; }
+ public Action OnItemEnqueued { get; set; }
- public Action OnItemDequeued { get; set; }
+ public Action OnItemDequeued { get; set; }
public void Enqueue(TaskItem item)
{
@@ -48,9 +42,8 @@ public void Enqueue(TaskItem item)
public TaskItem Dequeue()
{
var nextQueueItem = this._queues
- .FirstOrDefault(x => x.Value.HasItems)
- .Value?
- .Dequeue();
+ .FirstOrDefault(x => x.HasItems)
+ ?.Dequeue();
if (nextQueueItem != null)
{
@@ -62,7 +55,7 @@ public TaskItem Dequeue()
public void Remove(TaskItem item)
{
- if (this._queues[item.Priority].Remove(item))
+ if (this._queues[(int)item.Priority].Remove(item))
{
this.DecrementCounter(item);
}
@@ -72,43 +65,47 @@ internal void Clear()
{
foreach (var queue in this._queues)
{
- queue.Value.Clear();
+ queue.Clear();
}
}
private int EnqueueItem(TaskItem item)
{
- this._queues[item.Priority].Add(item);
-
- var count = this._counter.Increment();
-
- this.OnItemEnqueued?.Invoke(count, item);
+ this._queues[(int)item.Priority].Add(item);
- return count;
+ return IncrementCounter(item);
}
private void RejectLastItem()
{
var lastItem = this._queues
- .LastOrDefault(x => x.Value.HasItems)
- .Value?
- .DequeueLast();
+ .LastOrDefault(x => x.HasItems)
+ ?.DequeueLast();
if (lastItem == null)
{
return;
}
- this._counter.Decrement();
-
this.DecrementCounter(lastItem);
lastItem.Reject();
}
- private void DecrementCounter(TaskItem nextQueueItem)
+ private int IncrementCounter(TaskItem item)
+ {
+ var count = this._counter.Increment();
+ this.OnItemEnqueued?.Invoke(item);
+
+ return count;
+ }
+
+ private int DecrementCounter(TaskItem nextQueueItem)
{
- this.OnItemDequeued?.Invoke(this._counter.Decrement(), nextQueueItem);
+ var count = this._counter.Decrement();
+ this.OnItemDequeued?.Invoke(nextQueueItem);
+
+ return count;
}
}
}
diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props
index 1b0c8ed..ea593c9 100644
--- a/tests/Directory.Build.props
+++ b/tests/Directory.Build.props
@@ -2,7 +2,6 @@
-
-
+
diff --git a/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/Farfetch.LoadShedding.BenchmarkTests.csproj b/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/Farfetch.LoadShedding.BenchmarkTests.csproj
index acd0f7f..9c86fc7 100644
--- a/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/Farfetch.LoadShedding.BenchmarkTests.csproj
+++ b/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/Farfetch.LoadShedding.BenchmarkTests.csproj
@@ -18,8 +18,4 @@
-
-
-
-
diff --git a/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/TaskQueueBenchmarks.cs b/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/TaskQueueBenchmarks.cs
index 1d35106..4de6ccb 100644
--- a/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/TaskQueueBenchmarks.cs
+++ b/tests/benchmark/Farfetch.LoadShedding.BenchmarkTests/TaskQueueBenchmarks.cs
@@ -1,4 +1,4 @@
-using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
using Farfetch.LoadShedding.Tasks;
@@ -13,11 +13,11 @@ namespace Farfetch.LoadShedding.BenchmarkTests
[RankColumn]
public class TaskQueueBenchmarks
{
- private readonly TaskQueue _queue = new TaskQueue(int.MaxValue);
+ private readonly TaskQueue _queue = new(int.MaxValue);
- private readonly TaskQueue _emptyQueue = new TaskQueue(int.MaxValue);
+ private readonly TaskQueue _emptyQueue = new(int.MaxValue);
- private readonly TaskQueue _limitedQueue = new TaskQueue(1000);
+ private readonly TaskQueue _limitedQueue = new(1000);
[IterationSetup]
public void Initialize()
@@ -38,7 +38,7 @@ public void Initialize()
}
[Benchmark]
- public void TaskQueueWith1000Items_EnqueueFixedPriority() => this._queue.Enqueue(new TaskItem(0));
+ public void TaskQueueWith1000Items_EnqueueFixedPriority() => this._queue.Enqueue(new TaskItem(Priority.Critical));
[Benchmark]
public void TaskQueueEmpty_EnqueueRandomPriority() => this._emptyQueue.Enqueue(GetTaskRandomPriority());
@@ -50,7 +50,7 @@ public void Initialize()
public void TaskQueueWith1000Items_Dequeue() => this._queue.Dequeue();
[Benchmark]
- public void TaskQueue_EnqueueNewItem_LimitReached() => this._limitedQueue.Enqueue(new TaskItem(0));
+ public void TaskQueue_EnqueueNewItem_LimitReached() => this._limitedQueue.Enqueue(new TaskItem(Priority.Critical));
private static TaskItem GetTaskRandomPriority()
{
diff --git a/tests/integration-tests/Directory.Build.props b/tests/integration-tests/Directory.Build.props
new file mode 100644
index 0000000..d1dc7cd
--- /dev/null
+++ b/tests/integration-tests/Directory.Build.props
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/tests/performance-tests/Farfetch.LoadShedding.PerformanceTests/Farfetch.LoadShedding.PerformanceTests.csproj b/tests/performance-tests/Farfetch.LoadShedding.PerformanceTests/Farfetch.LoadShedding.PerformanceTests.csproj
index ca254b5..6fb0410 100644
--- a/tests/performance-tests/Farfetch.LoadShedding.PerformanceTests/Farfetch.LoadShedding.PerformanceTests.csproj
+++ b/tests/performance-tests/Farfetch.LoadShedding.PerformanceTests/Farfetch.LoadShedding.PerformanceTests.csproj
@@ -17,8 +17,4 @@
-
-
-
-
diff --git a/tests/unit-tests/Directory.Build.props b/tests/unit-tests/Directory.Build.props
new file mode 100644
index 0000000..81b2e1a
--- /dev/null
+++ b/tests/unit-tests/Directory.Build.props
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskItemTests.cs b/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskItemTests.cs
index ed50022..5ddfd6a 100644
--- a/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskItemTests.cs
+++ b/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskItemTests.cs
@@ -9,7 +9,7 @@ public class TaskItemTests
public async Task WaitAsync_Process_ReturnsProcessingStatus()
{
// Arrange
- var taskItem = new TaskItem(0);
+ var taskItem = new TaskItem(Priority.Critical);
var waitingTask = taskItem.WaitAsync(10000, CancellationToken.None);
@@ -26,7 +26,7 @@ public async Task WaitAsync_Process_ReturnsProcessingStatus()
public async Task WaitAsync_TimeoutReached_ReturnsCanceledStatus()
{
// Arrange
- var taskItem = new TaskItem(0);
+ var taskItem = new TaskItem(Priority.Critical);
var waitingTask = taskItem.WaitAsync(1, CancellationToken.None);
@@ -43,7 +43,7 @@ public async Task WaitAsync_TimeoutReached_ReturnsCanceledStatus()
public async Task WaitAsync_CancelledToken_ReturnsCanceledStatus()
{
// Arrange
- var taskItem = new TaskItem(0);
+ var taskItem = new TaskItem(Priority.Critical);
using var source = new CancellationTokenSource();
@@ -62,7 +62,7 @@ public async Task WaitAsync_CancelledToken_ReturnsCanceledStatus()
public async Task WaitAsync_Reject_ReturnsProcessingStatus()
{
// Arrange
- var taskItem = new TaskItem(0);
+ var taskItem = new TaskItem(Priority.Critical);
var waitingTask = taskItem.WaitAsync(10000, CancellationToken.None);
diff --git a/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskManagerTests.cs b/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskManagerTests.cs
index 0c9104d..ae7c10d 100644
--- a/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskManagerTests.cs
+++ b/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskManagerTests.cs
@@ -243,13 +243,12 @@ public async Task Release_ConcurrencyItemsIsNotZero_NotifyConcurrentItemsCountCh
var processingItems = new List();
var events = new LoadSheddingEvents();
-
events.ItemProcessed.Subscribe(args => processedItems.Add(args));
events.ItemProcessing.Subscribe(args => processingItems.Add(args));
var target = new TaskManager(10, 10, Timeout.Infinite, events);
- var item = await target.AcquireAsync(0);
+ var item = await target.AcquireAsync(Priority.Critical);
// Act
item.Complete();
@@ -257,7 +256,7 @@ public async Task Release_ConcurrencyItemsIsNotZero_NotifyConcurrentItemsCountCh
// Assert
Assert.Single(processingItems);
Assert.Equal(item.Priority, processingItems.First().Priority);
- Assert.Equal(1, processingItems.First().ConcurrencyCount);
+ Assert.Equal(0, processingItems.First().ConcurrencyCount);
Assert.Equal(10, processingItems.First().ConcurrencyLimit);
Assert.Single(processedItems);
diff --git a/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskQueueTests.cs b/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskQueueTests.cs
index 8cb2ad8..1fa3779 100644
--- a/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskQueueTests.cs
+++ b/tests/unit-tests/Farfetch.LoadShedding.Tests/Tasks/TaskQueueTests.cs
@@ -19,7 +19,7 @@ public TaskQueueTests()
public void Enqueue_QueueLimitNotReached_AddToQueue()
{
// Arrange
- var task = new TaskItem(0);
+ var task = new TaskItem(Priority.Critical);
// Act
this._target.Enqueue(task);
@@ -35,8 +35,8 @@ public void Enqueue_QueueLimitIsReached_RejectItem()
// Arrange
this._target.Limit = 1;
- var firstTask = new TaskItem(0);
- var lastTask = new TaskItem(0);
+ var firstTask = new TaskItem(Priority.Critical);
+ var lastTask = new TaskItem(Priority.Critical);
this._target.Enqueue(firstTask);
@@ -57,7 +57,7 @@ public void Enqueue_TaskWithHigherPriorityQueueLimitIsReached_EnqueueItemAndReje
var lowPriorityTask = new TaskItem(Priority.NonCritical);
this._target.Enqueue(lowPriorityTask);
- var highPriorityTask = new TaskItem(0);
+ var highPriorityTask = new TaskItem(Priority.Critical);
// Act
this._target.Enqueue(highPriorityTask);