mirror of
https://gricad-gitlab.univ-grenoble-alpes.fr/tienyoun/presentations.git
synced 2026-09-26 13:31:01 +00:00
celery sse
This commit is contained in:
@@ -0,0 +1 @@
|
||||
https://gricad-gitlab.univ-grenoble-alpes.fr/tienyoun/presentations
|
||||
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
Plugin for embedding mermaid.js diagrams in reveal.js presentations
|
||||
GitHub: https://github.com/dainiak/revealjs-plugins/
|
||||
|
||||
Author: Alex Dainiak
|
||||
Web: www.dainiak.com
|
||||
Email: dainiak@gmail.com
|
||||
|
||||
Processing rules can be added to post-process the diagram SVG DOM subtree.
|
||||
One can set the id, set or remove classes, or set attributes on the SVG elements. In any combinations:
|
||||
%%% someCssSelector -> #cssIdToSet .css-class-to-set !.class-to-remove [some-property-to-set=newValue]
|
||||
If the `->` arrow is used then the modifications are applied to the element itself.
|
||||
If the `^->` arrow is used then the element is wrapped with a g element and modifications are applied to this g.
|
||||
If the `_->` arrow is used then a single g is added as the only new child of the element and the modifications are applied to this g. All the former children are moved inside this g.
|
||||
You can use [n] right after the selector to target a specific element in the list of matching elements. Works even when `:nth-child` does not.
|
||||
Examples:
|
||||
%% Apply .fragment class to the first of the mermaid nodes:
|
||||
%%% g.node[1] -> .fragment
|
||||
|
||||
%% Make the "Start" node a fragment step and red
|
||||
%%% rect[id*="A"] _-> .fragment .fade-up [data-fragment-index=1]
|
||||
|
||||
%% Remove default class and add new one
|
||||
%%% #D -> !.node .end-state
|
||||
*/
|
||||
|
||||
const RevealMermaid = {
|
||||
id: 'mermaid',
|
||||
init: async (reveal) => {
|
||||
const katexVersion = '0.16.27';
|
||||
const mermaidVersion = '11.14.0';
|
||||
let options = reveal.getConfig().mermaid || {};
|
||||
options = {
|
||||
mathInLabels: options.mathInLabels !== false,
|
||||
urls: options.urls || {
|
||||
mermaid: options.urls && options.urls.mermaid || `./assets/mermaid.min.js`,
|
||||
katex: options.urls && options.urls.katex || `https://cdn.jsdelivr.net/npm/katex@${katexVersion}/dist/katex.min.js`,
|
||||
katexCss: options.urls && options.urls.katexCss || `https://cdn.jsdelivr.net/npm/katex@${katexVersion}/dist/katex.min.css`,
|
||||
},
|
||||
selectors: {
|
||||
container: options.selectors && options.selectors.container || '[data-mermaid]',
|
||||
script: options.selectors && options.selectors.script || 'script[type="text/mermaid"]',
|
||||
},
|
||||
overflowVisible: options.overflowVisible === undefined ? true : options.overflowVisible,
|
||||
mermaidInit: options.mermaidInit || {
|
||||
startOnLoad: false,
|
||||
theme: 'auto',
|
||||
suppressErrorRendering: true
|
||||
},
|
||||
iconPacks: options.iconPacks || [],
|
||||
css: {
|
||||
enabled: options?.css?.enabled !== false,
|
||||
cssIndices: options?.css?.cssIndices !== false,
|
||||
indexClassPrefix: options?.css?.indexClassPrefix || 'fragidx-',
|
||||
debug: options?.css?.debug || false
|
||||
}
|
||||
};
|
||||
|
||||
let scriptsToLoad = [
|
||||
{
|
||||
url: options.urls.mermaid,
|
||||
condition:
|
||||
!window.mermaid
|
||||
&& !document.querySelector(`script[src="${options.mermaidUrl}"]`)
|
||||
}, {
|
||||
url: options.urls.katex,
|
||||
condition:
|
||||
options.mathInLabels
|
||||
&& !window.katex
|
||||
&& !document.querySelector(`script[src="${options.katexUrl}"]`)
|
||||
},{
|
||||
url: options.urls.katexCss,
|
||||
type: 'text/css',
|
||||
condition:
|
||||
!window.vegaEmbed
|
||||
&& !window.katex
|
||||
}
|
||||
];
|
||||
|
||||
function loadScript(params) {
|
||||
return new Promise((resolve) => {
|
||||
if(params.condition !== undefined
|
||||
&& !(params.condition === true || typeof params.condition == 'function' && params.condition.call())) {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
if( params.type === undefined )
|
||||
params.type = (params.url && params.url.match(/\.css[^.]*$/)) ? 'text/css' : 'text/javascript';
|
||||
|
||||
let element;
|
||||
|
||||
if( params.type === 'text/css' ){
|
||||
if( params.content ){
|
||||
element = document.createElement('style');
|
||||
element.textContent = params.content;
|
||||
}
|
||||
else {
|
||||
element = document.createElement('link');
|
||||
element.rel = 'stylesheet';
|
||||
element.type = 'text/css';
|
||||
element.href = params.url;
|
||||
}
|
||||
}
|
||||
else {
|
||||
element = document.createElement('script');
|
||||
element.type = params.type || 'text/javascript';
|
||||
if( params.content )
|
||||
element.textContent = params.content;
|
||||
else
|
||||
element.src = params.url;
|
||||
}
|
||||
|
||||
if(params.content){
|
||||
document.querySelector('head').appendChild(element);
|
||||
resolve();
|
||||
}
|
||||
else {
|
||||
element.onload = resolve;
|
||||
document.querySelector( 'head' ).appendChild(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if(!reveal.getSlidesElement().querySelector(options.selectors.container))
|
||||
return;
|
||||
|
||||
|
||||
// Load mermaid, katex, and katex CSS in parallel (they are independent)
|
||||
await Promise.all(scriptsToLoad.map(s => loadScript(s)));
|
||||
|
||||
if((options.mermaidInit.theme || 'auto') === 'auto') {
|
||||
options.mermaidInit.theme = 'default';
|
||||
if(document.querySelector(
|
||||
'[href*="black.css"],[href*="league.css"],[href*="night.css"],[href*="moon.css"],[href*="dracula.css"],[href*="blood.css"]'
|
||||
)) {
|
||||
options.mermaidInit.theme = 'dark';
|
||||
}
|
||||
}
|
||||
|
||||
window.mermaid.initialize(options.mermaidInit);
|
||||
|
||||
if(options.iconPacks) {
|
||||
for(let packName in options.iconPacks) {
|
||||
window.mermaid.registerIconPacks([
|
||||
{
|
||||
name: packName,
|
||||
loader: () =>
|
||||
fetch(options.iconPacks[packName]).then((res) => res.json()),
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function dedentAndTrim(str) {
|
||||
const TAB_WIDTH = 4;
|
||||
const lines = str.split(/\r?\n/);
|
||||
let minIndent = Infinity;
|
||||
|
||||
for (const line of lines) {
|
||||
if (!line.trim()) continue;
|
||||
let width = 0;
|
||||
for (const char of line) {
|
||||
if (char === ' ') width++;
|
||||
else if (char === '\t') width += TAB_WIDTH;
|
||||
else break;
|
||||
}
|
||||
if (width < minIndent) minIndent = width;
|
||||
}
|
||||
|
||||
if (minIndent === Infinity) minIndent = 0;
|
||||
|
||||
return lines.map(line => {
|
||||
let width = 0, i = 0;
|
||||
for (; i < line.length; i++) {
|
||||
if (width >= minIndent) break;
|
||||
const char = line[i];
|
||||
if (char === ' ') width++;
|
||||
else if (char === '\t') width += TAB_WIDTH;
|
||||
else break;
|
||||
}
|
||||
return ' '.repeat(Math.max(0, width - minIndent)) + line.slice(i);
|
||||
}).join('\n').trim();
|
||||
}
|
||||
|
||||
const mermaidContainers = Array.from(reveal.getSlidesElement().querySelectorAll(options.selectors.container));
|
||||
|
||||
const renderPromises = mermaidContainers.map(async (mermaidContainer) => {
|
||||
const parent = mermaidContainer.parentNode;
|
||||
const newDiv = document.createElement('div');
|
||||
parent.insertBefore(newDiv, mermaidContainer);
|
||||
|
||||
const mermaidScript = mermaidContainer.querySelector("script");
|
||||
if(mermaidScript) {
|
||||
mermaidScript.textContent = dedentAndTrim(mermaidScript.textContent);
|
||||
}
|
||||
|
||||
if(!mermaidContainer.id)
|
||||
mermaidContainer.id = `mermaid-${Math.floor(Math.random() * 1000000)}`;
|
||||
|
||||
let graphDefinition;
|
||||
const mermaidAttrValue = mermaidContainer.getAttribute('data-mermaid');
|
||||
if(mermaidAttrValue && mermaidAttrValue.trim() !== '') {
|
||||
try {
|
||||
const response = await fetch(mermaidAttrValue.trim());
|
||||
if(!response.ok)
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
graphDefinition = await response.text();
|
||||
} catch(error) {
|
||||
console.warn(`Mermaid Plugin: Failed to fetch diagram from "${mermaidAttrValue}":`, error);
|
||||
mermaidContainer.remove();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const scriptEl = mermaidContainer.querySelector(options.selectors.script);
|
||||
if(!scriptEl) {
|
||||
console.warn('Mermaid Plugin: No script element or data-mermaid path found in container', mermaidContainer);
|
||||
mermaidContainer.remove();
|
||||
return;
|
||||
}
|
||||
graphDefinition = scriptEl.innerHTML;
|
||||
}
|
||||
let renderRules = [];
|
||||
|
||||
// 1. Extract Custom CSS Logic
|
||||
// Regex matches: selector + (one of ->, ^->, _->) + assignment
|
||||
const ruleRegex = /^\s*%%%\s+(.+?)\s+([\^_]?->)\s+(.+?)\s*$/gm;
|
||||
|
||||
graphDefinition = graphDefinition.replace(ruleRegex, (match, selector, arrow, assignment) => {
|
||||
renderRules.push({
|
||||
selector,
|
||||
assignment,
|
||||
type: arrow
|
||||
});
|
||||
return match;
|
||||
});
|
||||
|
||||
// 2. Handle Math in Labels
|
||||
if(options.mathInLabels) {
|
||||
graphDefinition = graphDefinition.replace(/\\([(\[]).*?\\([)\]])/g, (s) => {
|
||||
let output = window.katex.renderToString(s.substring(2, s.length - 2), {
|
||||
output: 'html',
|
||||
displayMode: s[1] === '['
|
||||
});
|
||||
return output.replaceAll('"', "'");
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Render Mermaid
|
||||
try {
|
||||
await window.mermaid.parse(graphDefinition, {suppressErrors: false});
|
||||
} catch (error) {
|
||||
console.warn(`Mermaid diagram failed to parse:\n\n${graphDefinition}\n\nError: `, error);
|
||||
mermaidContainer.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
let svg;
|
||||
try {
|
||||
({ svg } = await window.mermaid.render(mermaidContainer.id, graphDefinition));
|
||||
} catch (error) {
|
||||
console.warn(`Mermaid diagram failed to render:\n\n${graphDefinition}\n\nError: `, error);
|
||||
mermaidContainer.remove();
|
||||
return;
|
||||
}
|
||||
newDiv.outerHTML = svg;
|
||||
const svgElement = parent.querySelector(`#${mermaidContainer.id}`);
|
||||
|
||||
// Copy classes and styles from container
|
||||
svgElement.classList += " " + mermaidContainer.classList;
|
||||
const hasStretchClass = mermaidContainer.classList.contains("r-stretch");
|
||||
if(hasStretchClass) {
|
||||
svgElement.style.width = "";
|
||||
svgElement.style.height = "";
|
||||
svgElement.style.maxWidth = "";
|
||||
svgElement.style.maxHeight = "";
|
||||
svgElement.style.minWidth = "";
|
||||
svgElement.style.minHeight = "";
|
||||
}
|
||||
for (const prop of mermaidContainer.style) {
|
||||
const value = mermaidContainer.style.getPropertyValue(prop);
|
||||
if (value && value.trim() !== '') {
|
||||
svgElement.style.setProperty(prop, value);
|
||||
}
|
||||
}
|
||||
mermaidContainer.remove();
|
||||
|
||||
// 4. Handle Overflow
|
||||
if(options.overflowVisible) {
|
||||
let selector = options.overflowVisible === '*' ? '*' : 'foreignObject';
|
||||
svgElement.querySelectorAll(selector).forEach((obj) => {
|
||||
obj.setAttribute('overflow', 'visible');
|
||||
});
|
||||
}
|
||||
|
||||
// 5. Apply Custom CSS Logic
|
||||
if (options.css.enabled && renderRules.length > 0) {
|
||||
const svgNS = "http://www.w3.org/2000/svg";
|
||||
|
||||
renderRules.forEach(({ selector, assignment, type }) => {
|
||||
try {
|
||||
selector = selector.trim();
|
||||
let indexPart = null;
|
||||
if(/.*\[\d+]$/.exec(selector)) {
|
||||
const digitPart = /\[\d+]$/.exec(selector)[0];
|
||||
indexPart = parseInt(digitPart.match(/\d+/)[0]);
|
||||
selector = selector.replace(/\[\d+]$/, '');
|
||||
}
|
||||
|
||||
const targets = svgElement.querySelectorAll(selector);
|
||||
targets.forEach((el, idx) => {
|
||||
if(indexPart !== null && idx + 1 !== indexPart)
|
||||
return;
|
||||
|
||||
if(options.css.debug) {
|
||||
console.log(selector, idx + 1, type, el)
|
||||
}
|
||||
|
||||
let modificationTarget = el;
|
||||
|
||||
// --- LOGIC FOR ARROW TYPES ---
|
||||
if (type === '^->') {
|
||||
// 1. OUTER WRAPPER
|
||||
// Wraps the element in a new <g> and modifies the <g>
|
||||
const wrapper = document.createElementNS(svgNS, 'g');
|
||||
el.parentNode.insertBefore(wrapper, el);
|
||||
wrapper.appendChild(el);
|
||||
modificationTarget = wrapper;
|
||||
|
||||
} else if (type === '_->') {
|
||||
// 2. INNER WRAPPER
|
||||
// Creates a new <g> inside the element, moves all children into it,
|
||||
// and modifies that new internal <g>
|
||||
const innerGroup = document.createElementNS(svgNS, 'g');
|
||||
|
||||
// Move all existing children of 'el' into 'innerGroup'
|
||||
while (el.firstChild) {
|
||||
innerGroup.appendChild(el.firstChild);
|
||||
}
|
||||
|
||||
el.appendChild(innerGroup);
|
||||
modificationTarget = innerGroup;
|
||||
}
|
||||
// Default '->' falls through here, keeping modificationTarget = el
|
||||
|
||||
const tokens = assignment.match(/(\[.+?\])|(\S+)/g) || [];
|
||||
|
||||
tokens.forEach(token => {
|
||||
if (token.startsWith('.')) {
|
||||
modificationTarget.classList.add(token.substring(1));
|
||||
} else if (token.startsWith('!.')) {
|
||||
modificationTarget.classList.remove(token.substring(2));
|
||||
} else if (token.startsWith('#')) {
|
||||
modificationTarget.id = token.substring(1);
|
||||
} else if (token.startsWith('[')) {
|
||||
const content = token.substring(1, token.length - 1);
|
||||
const eqIndex = content.indexOf('=');
|
||||
|
||||
if (eqIndex > -1) {
|
||||
const key = content.substring(0, eqIndex).trim();
|
||||
let val = content.substring(eqIndex + 1).trim();
|
||||
|
||||
if ((val.startsWith('"') && val.endsWith('"')) ||
|
||||
(val.startsWith("'") && val.endsWith("'"))) {
|
||||
val = val.substring(1, val.length - 1);
|
||||
}
|
||||
|
||||
modificationTarget.setAttribute(key, val);
|
||||
} else {
|
||||
modificationTarget.setAttribute(content, '');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(`Mermaid Plugin: Failed to apply selector "${selector}".`, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(options.css.enabled && options.css.cssIndices) {
|
||||
const cssSelector = '[class*="' + options.css.indexClassPrefix + '"]';
|
||||
const fragmentsWithCssIndex = svgElement.querySelectorAll(cssSelector);
|
||||
|
||||
for (let fragment of fragmentsWithCssIndex) {
|
||||
let s = fragment.getAttribute('class');
|
||||
s = s.substring(
|
||||
s.indexOf(options.css.indexClassPrefix) + options.css.indexClassPrefix.length
|
||||
);
|
||||
s = s.substring(0, Math.max(s.indexOf(' '), s.length));
|
||||
fragment.classList.add('fragment');
|
||||
fragment.setAttribute('data-fragment-index', s);
|
||||
}
|
||||
}
|
||||
|
||||
if(hasStretchClass)
|
||||
svgElement.style.height = '100%';
|
||||
});
|
||||
|
||||
await Promise.all(renderPromises);
|
||||
reveal.layout();
|
||||
}
|
||||
};
|
||||
Vendored
+3597
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 34 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,15 @@
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
%%{init: {'theme': 'light', 'themeVariables': { 'darkMode': false }}}%%
|
||||
sequenceDiagram
|
||||
actor Web Browser
|
||||
participant Django
|
||||
participant RabbitMQ@{ "type" : "database" }
|
||||
Web Browser->>+Django: GET /progress
|
||||
Django-->>Web Browser: List of current tasks
|
||||
Django->>+RabbitMQ: Listen for events
|
||||
RabbitMQ-->>Django: Steam of events
|
||||
Django-->>Web Browser: Steam of events
|
||||
deactivate Django
|
||||
</script>
|
||||
</div>
|
||||
@@ -0,0 +1,176 @@
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
user -- "GET /progress" --> django
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 0"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
django --- thread
|
||||
django --- queue
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 0"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
thread -- "subscribe" --> rabbitMQ
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 1"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
celery --> rabbitMQ
|
||||
rabbitMQ -- "message" --> thread
|
||||
thread --> queue
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 0"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
queue -- "consume queue" --> django
|
||||
django -- "send SSE message" --> user
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 1"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
celery --> rabbitMQ
|
||||
rabbitMQ -- "message" --> thread
|
||||
thread --> queue
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 2"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
celery --> rabbitMQ
|
||||
rabbitMQ -- "message" --> thread
|
||||
thread --> queue
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 1"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
queue -- "consume queue" --> django
|
||||
django -- "send SSE message" --> user
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- .slide: data-transition="none" -->
|
||||
|
||||
<div data-mermaid>
|
||||
<script type="text/mermaid">
|
||||
block
|
||||
columns 7
|
||||
space:5 rabbitMQ(("RabbitMQ")) space
|
||||
user(("User")) space:2 django(("Django")) space:2 celery(("Celery"))
|
||||
space:2 queue["Queue\nlength: 0"] space thread space:2
|
||||
user -- "SSE Connection" --- django
|
||||
queue -- "consume queue" --> django
|
||||
django -- "send SSE message" --> user
|
||||
style user fill:#ffe0b2,stroke:#fb8c00
|
||||
style celery fill:#bbdefb,stroke:#1e88e5
|
||||
style rabbitMQ fill:#effbb2,stroke:#797f5b
|
||||
</script>
|
||||
</div>
|
||||
@@ -0,0 +1,83 @@
|
||||
<div data-mermaid class="r-stretch">
|
||||
<script type="text/mermaid">
|
||||
%%{init: {'theme': 'light', 'themeVariables': { 'darkMode': false }}}%%
|
||||
sequenceDiagram
|
||||
actor Web Browser
|
||||
participant Django
|
||||
future participant Queue
|
||||
future participant Django-Thread
|
||||
Web Browser->>+Django: GET /progress
|
||||
create participant Django-Thread
|
||||
Django->>+Django-Thread: Create thread
|
||||
create participant Queue
|
||||
Django-Thread-->>Queue: Create queue
|
||||
Django-Thread-->>Django: <<[Queue]>>
|
||||
Django-Thread->>+RabbitMQ: Subscribe
|
||||
Django-Thread-)+Queue: <<current celery tasks>>
|
||||
par RabbitMQ Listen Thread
|
||||
loop RabbitMQ Communication
|
||||
RabbitMQ-)Django-Thread: <<event>>
|
||||
Django-Thread->>Queue: <<event>>
|
||||
end
|
||||
loop heartbeat
|
||||
Django-Thread->>Queue: <<event>>
|
||||
end
|
||||
and Django SSE Thread
|
||||
loop SSE Communication
|
||||
Django->>Queue: queue.get()
|
||||
Queue-->>Django: <<event>>
|
||||
deactivate Queue
|
||||
Django->>Web Browser: <<event>>
|
||||
end
|
||||
end
|
||||
deactivate Django
|
||||
deactivate Django-Thread
|
||||
</script>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<!--Client leaves-->
|
||||
<div data-mermaid class="r-stretch">
|
||||
<script type="text/mermaid">
|
||||
%%{init: {'theme': 'light', 'themeVariables': { 'darkMode': false }}}%%
|
||||
sequenceDiagram
|
||||
actor Web Browser
|
||||
participant Django
|
||||
future participant Queue
|
||||
future participant Django-Thread
|
||||
Web Browser->>+Django: GET /progress
|
||||
create participant Django-Thread
|
||||
Django->>Django-Thread: Create thread
|
||||
create participant Queue
|
||||
Django-Thread-->>Queue: Create queue
|
||||
Django-Thread-->>Django: <<[Queue]>>
|
||||
Django-Thread->>+RabbitMQ: Subscribe
|
||||
Django-Thread-)Queue: <<current celery tasks>>
|
||||
par RabbitMQ Listen Thread
|
||||
loop RabbitMQ Communication
|
||||
RabbitMQ-)Django-Thread: <<event>>
|
||||
Django-Thread->>Queue: <<event>>
|
||||
break Queue is full
|
||||
Django-Thread-xQueue: <<event>>
|
||||
Django-Thread-xDjango-Thread: Kill self
|
||||
destroy Django-Thread
|
||||
Django-Thread-xDjango-Thread:
|
||||
end
|
||||
end
|
||||
and Django SSE Thread
|
||||
loop SSE Communication
|
||||
Django->>Queue: queue.get()
|
||||
Queue-->>Django: <<event>>
|
||||
Django->>Web Browser: <<event>>
|
||||
break Timeout while waiting for messages
|
||||
destroy Web Browser
|
||||
Django-xWeb Browser: Close connection
|
||||
Deactivate Django
|
||||
destroy Queue
|
||||
Django-xQueue: garbage collector
|
||||
end
|
||||
end
|
||||
end
|
||||
</script>
|
||||
</div>
|
||||
Reference in New Issue
Block a user