- Add complete API documentation and architecture guides - Include quick start, installation, and deployment guides - Add troubleshooting and security documentation - Include CLI reference and configuration schema docs - Add production monitoring and operations guides - Implement MkDocs configuration with search functionality - Include comprehensive user and developer documentation Provides complete documentation for users and developers covering all aspects of the FetchML platform.
2140 lines
No EOL
65 KiB
HTML
2140 lines
No EOL
65 KiB
HTML
|
|
<!doctype html>
|
|
<html lang="en" class="no-js">
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
|
|
<meta name="description" content="Secure Machine Learning Platform">
|
|
|
|
|
|
|
|
|
|
<link rel="prev" href="../zig-cli/">
|
|
|
|
|
|
<link rel="next" href="../smart-defaults/">
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="icon" href="../assets/images/favicon.png">
|
|
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.0">
|
|
|
|
|
|
|
|
<title>Task Queue Architecture - Fetch ML Documentation</title>
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../assets/stylesheets/main.618322db.min.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
|
|
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
|
|
|
|
|
|
|
|
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
|
|
|
|
|
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="blue" data-md-color-accent="blue">
|
|
|
|
|
|
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
|
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
|
<label class="md-overlay" for="__drawer"></label>
|
|
<div data-md-component="skip">
|
|
|
|
|
|
<a href="#task-queue-architecture" class="md-skip">
|
|
Skip to content
|
|
</a>
|
|
|
|
</div>
|
|
<div data-md-component="announce">
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<header class="md-header" data-md-component="header">
|
|
<nav class="md-header__inner md-grid" aria-label="Header">
|
|
<a href=".." title="Fetch ML Documentation" class="md-header__button md-logo" aria-label="Fetch ML Documentation" data-md-component="logo">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
|
|
|
|
</a>
|
|
<label class="md-header__button md-icon" for="__drawer">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
|
|
</label>
|
|
<div class="md-header__title" data-md-component="header-title">
|
|
<div class="md-header__ellipsis">
|
|
<div class="md-header__topic">
|
|
<span class="md-ellipsis">
|
|
Fetch ML Documentation
|
|
</span>
|
|
</div>
|
|
<div class="md-header__topic" data-md-component="header-topic">
|
|
<span class="md-ellipsis">
|
|
|
|
Task Queue Architecture
|
|
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<form class="md-header__option" data-md-component="palette">
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="blue" data-md-color-accent="blue" aria-hidden="true" type="radio" name="__palette" id="__palette_0">
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="blue" data-md-color-accent="blue" aria-hidden="true" type="radio" name="__palette" id="__palette_1">
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-header__button md-icon" for="__search">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
|
</label>
|
|
<div class="md-search" data-md-component="search" role="dialog">
|
|
<label class="md-search__overlay" for="__search"></label>
|
|
<div class="md-search__inner" role="search">
|
|
<form class="md-search__form" name="search">
|
|
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
|
<label class="md-search__icon md-icon" for="__search">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
|
</label>
|
|
<nav class="md-search__options" aria-label="Search">
|
|
|
|
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
|
|
</a>
|
|
|
|
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
</button>
|
|
</nav>
|
|
|
|
</form>
|
|
<div class="md-search__output">
|
|
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
|
|
<div class="md-search-result" data-md-component="search-result">
|
|
<div class="md-search-result__meta">
|
|
Initializing search
|
|
</div>
|
|
<ol class="md-search-result__list" role="presentation"></ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-header__source">
|
|
<a href="https://github.com/jfraeys/fetch_ml" title="Go to repository" class="md-source" data-md-component="source">
|
|
<div class="md-source__icon md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
GitHub
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
</header>
|
|
|
|
<div class="md-container" data-md-component="container">
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
|
|
<div class="md-grid">
|
|
<ul class="md-tabs__list">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href=".." class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Home
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../quick-start/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Getting Started
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item md-tabs__item--active">
|
|
<a href="../development-setup/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Development
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../deployment/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Operations & Production
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../security/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Security
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
<a href="../configuration-schema/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
Reference
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
|
|
|
|
|
|
<main class="md-main" data-md-component="main">
|
|
<div class="md-main__inner md-grid">
|
|
|
|
|
|
|
|
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
|
<div class="md-sidebar__scrollwrap">
|
|
<div class="md-sidebar__inner">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
|
|
<label class="md-nav__title" for="__drawer">
|
|
<a href=".." title="Fetch ML Documentation" class="md-nav__button md-logo" aria-label="Fetch ML Documentation" data-md-component="logo">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
|
|
|
|
</a>
|
|
Fetch ML Documentation
|
|
</label>
|
|
|
|
<div class="md-nav__source">
|
|
<a href="https://github.com/jfraeys/fetch_ml" title="Go to repository" class="md-source" data-md-component="source">
|
|
<div class="md-source__icon md-icon">
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
|
</div>
|
|
<div class="md-source__repository">
|
|
GitHub
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href=".." class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Home
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2" >
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Getting Started
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_2">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Getting Started
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../quick-start/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Quick Start
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../installation/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Simple Installation Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../first-experiment/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
First Experiment
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Development
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
|
|
<label class="md-nav__title" for="__nav_3">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Development
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../development-setup/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Development Setup
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../testing/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Testing Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../architecture/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Homelab Architecture
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../cli-reference/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
CLI Reference
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../zig-cli/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Zig CLI Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--active">
|
|
|
|
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__link md-nav__link--active" for="__toc">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Task Queue Architecture
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<a href="./" class="md-nav__link md-nav__link--active">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Task Queue Architecture
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__title" for="__toc">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
Table of contents
|
|
</label>
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#overview" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Overview
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#components" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Components
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Components">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#taskqueue-internalqueue" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
TaskQueue (internal/queue)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="TaskQueue (internal/queue)">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#task-structure" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Task Structure
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#taskqueue-interface" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
TaskQueue Interface
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#data-flow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Data Flow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Data Flow">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#job-submission-flow" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Job Submission Flow
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#protocol" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Protocol
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#redis-data-structures" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Redis Data Structures
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Redis Data Structures">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#keys" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Keys
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#priority-queue-zset" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Priority Queue (ZSET)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#api-server-integration" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
API Server Integration
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="API Server Integration">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#initialization" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Initialization
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#websocket-handler" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
WebSocket Handler
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#worker-integration" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Worker Integration
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Worker Integration">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#task-polling" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Task Polling
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#task-execution" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Task Execution
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#configuration" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Configuration
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Configuration">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#api-server-configsconfigyaml" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
API Server (configs/config.yaml)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#worker-configsworker-configyaml" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Worker (configs/worker-config.yaml)
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#monitoring" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Monitoring
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Monitoring">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#queue-depth" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Queue Depth
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#worker-heartbeat" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Worker Heartbeat
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#metrics" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Metrics
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#error-handling" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Error Handling
|
|
|
|
</span>
|
|
</a>
|
|
|
|
<nav class="md-nav" aria-label="Error Handling">
|
|
<ul class="md-nav__list">
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#task-failures" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Task Failures
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#redis-connection-loss" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Redis Connection Loss
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#testing" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Testing
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#best-practices" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
|
|
Best Practices
|
|
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../smart-defaults/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Smart Defaults
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../cicd/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
CI/CD Pipeline
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4" >
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Operations & Production
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_4">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Operations & Production
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../deployment/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
ML Experiment Manager - Deployment Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../environment-variables/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Environment Variables
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../production-monitoring/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Production Monitoring Deployment Guide (Linux)
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../operations/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Operations Runbook
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../redis-ha/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Redis High Availability (Optional)
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../release-checklist/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Release Checklist
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5" >
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Security
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_5">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Security
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../security/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Security Guide
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../api-key-process/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
FetchML API Key Process
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../user-permissions/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
User Permissions in Fetch ML
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Reference
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
|
|
<label class="md-nav__title" for="__nav_6">
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
|
|
|
Reference
|
|
|
|
|
|
</label>
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../configuration-schema/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Configuration Schema
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
<a href="../troubleshooting/" class="md-nav__link">
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Troubleshooting
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="md-content" data-md-component="content">
|
|
|
|
<article class="md-content__inner md-typeset">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h1 id="task-queue-architecture">Task Queue Architecture<a class="headerlink" href="#task-queue-architecture" title="Permanent link">¶</a></h1>
|
|
<p>The task queue system enables reliable job processing between the API server and workers using Redis.</p>
|
|
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">¶</a></h2>
|
|
<div class="highlight"><pre><span></span><code>graph LR
|
|
CLI[CLI/Client] -->|WebSocket| API[API Server]
|
|
API -->|Enqueue| Redis[(Redis)]
|
|
Redis -->|Dequeue| Worker[Worker]
|
|
Worker -->|Update Status| Redis
|
|
</code></pre></div>
|
|
<h2 id="components">Components<a class="headerlink" href="#components" title="Permanent link">¶</a></h2>
|
|
<h3 id="taskqueue-internalqueue">TaskQueue (<code>internal/queue</code>)<a class="headerlink" href="#taskqueue-internalqueue" title="Permanent link">¶</a></h3>
|
|
<p>Shared package used by both API server and worker for job management.</p>
|
|
<h4 id="task-structure">Task Structure<a class="headerlink" href="#task-structure" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><span class="kd">type</span><span class="w"> </span><span class="nx">Task</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">ID</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="c1">// Unique task ID (UUID)</span>
|
|
<span class="w"> </span><span class="nx">JobName</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="c1">// User-defined job name </span>
|
|
<span class="w"> </span><span class="nx">Args</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="c1">// Job arguments</span>
|
|
<span class="w"> </span><span class="nx">Status</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="c1">// queued, running, completed, failed</span>
|
|
<span class="w"> </span><span class="nx">Priority</span><span class="w"> </span><span class="kt">int64</span><span class="w"> </span><span class="c1">// Higher = executed first</span>
|
|
<span class="w"> </span><span class="nx">CreatedAt</span><span class="w"> </span><span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="nx">StartedAt</span><span class="w"> </span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="nx">EndedAt</span><span class="w"> </span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Time</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="nx">WorkerID</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="nx">Error</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="nx">Datasets</span><span class="w"> </span><span class="p">[]</span><span class="kt">string</span><span class="w"> </span>
|
|
<span class="w"> </span><span class="nx">Metadata</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="w"> </span><span class="c1">// commit_id, user, etc</span>
|
|
<span class="p">}</span>
|
|
</code></pre></div>
|
|
<h4 id="taskqueue-interface">TaskQueue Interface<a class="headerlink" href="#taskqueue-interface" title="Permanent link">¶</a></h4>
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// Initialize queue</span>
|
|
<span class="nx">queue</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">NewTaskQueue</span><span class="p">(</span><span class="nx">queue</span><span class="p">.</span><span class="nx">Config</span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">RedisAddr</span><span class="p">:</span><span class="w"> </span><span class="s">"localhost:6379"</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">RedisPassword</span><span class="p">:</span><span class="w"> </span><span class="s">""</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">RedisDB</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
|
<span class="p">})</span>
|
|
|
|
<span class="c1">// Add task (API server)</span>
|
|
<span class="nx">task</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&</span><span class="nx">queue</span><span class="p">.</span><span class="nx">Task</span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">ID</span><span class="p">:</span><span class="w"> </span><span class="nx">uuid</span><span class="p">.</span><span class="nx">New</span><span class="p">().</span><span class="nx">String</span><span class="p">(),</span>
|
|
<span class="w"> </span><span class="nx">JobName</span><span class="p">:</span><span class="w"> </span><span class="s">"train-model"</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">Status</span><span class="p">:</span><span class="w"> </span><span class="s">"queued"</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">Priority</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">Metadata</span><span class="p">:</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
|
|
<span class="w"> </span><span class="s">"commit_id"</span><span class="p">:</span><span class="w"> </span><span class="nx">commitID</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="s">"user"</span><span class="p">:</span><span class="w"> </span><span class="nx">username</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="p">},</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">err</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">AddTask</span><span class="p">(</span><span class="nx">task</span><span class="p">)</span>
|
|
|
|
<span class="c1">// Get next task (Worker)</span>
|
|
<span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">GetNextTask</span><span class="p">()</span>
|
|
|
|
<span class="c1">// Update task status</span>
|
|
<span class="nx">task</span><span class="p">.</span><span class="nx">Status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"running"</span>
|
|
<span class="nx">err</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">UpdateTask</span><span class="p">(</span><span class="nx">task</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
<h2 id="data-flow">Data Flow<a class="headerlink" href="#data-flow" title="Permanent link">¶</a></h2>
|
|
<h3 id="job-submission-flow">Job Submission Flow<a class="headerlink" href="#job-submission-flow" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code>sequenceDiagram
|
|
participant CLI
|
|
participant API
|
|
participant Redis
|
|
participant Worker
|
|
|
|
CLI->>API: Queue Job (WebSocket)
|
|
API->>API: Create Task (UUID)
|
|
API->>Redis: ZADD task:queue
|
|
API->>Redis: SET task:{id}
|
|
API->>CLI: Success Response
|
|
|
|
Worker->>Redis: ZPOPMAX task:queue
|
|
Redis->>Worker: Task ID
|
|
Worker->>Redis: GET task:{id}
|
|
Redis->>Worker: Task Data
|
|
Worker->>Worker: Execute Job
|
|
Worker->>Redis: Update Status
|
|
</code></pre></div>
|
|
<h3 id="protocol">Protocol<a class="headerlink" href="#protocol" title="Permanent link">¶</a></h3>
|
|
<p><strong>CLI → API</strong> (Binary WebSocket):
|
|
<div class="highlight"><pre><span></span><code>[opcode:1][api_key_hash:64][commit_id:64][priority:1][job_name_len:1][job_name:var]
|
|
</code></pre></div></p>
|
|
<p><strong>API → Redis</strong>:
|
|
- Priority queue: <code>ZADD task:queue {priority} {task_id}</code>
|
|
- Task data: <code>SET task:{id} {json}</code>
|
|
- Status: <code>HSET task:status:{job_name} ...</code></p>
|
|
<p><strong>Worker ← Redis</strong>:
|
|
- Poll: <code>ZPOPMAX task:queue 1</code> (highest priority first)
|
|
- Fetch: <code>GET task:{id}</code></p>
|
|
<h2 id="redis-data-structures">Redis Data Structures<a class="headerlink" href="#redis-data-structures" title="Permanent link">¶</a></h2>
|
|
<h3 id="keys">Keys<a class="headerlink" href="#keys" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code>task:queue # ZSET: priority queue
|
|
task:{uuid} # STRING: task JSON data
|
|
task:status:{job_name} # HASH: job status
|
|
worker:heartbeat # HASH: worker health
|
|
job:metrics:{job_name} # HASH: job metrics
|
|
</code></pre></div>
|
|
<h3 id="priority-queue-zset">Priority Queue (ZSET)<a class="headerlink" href="#priority-queue-zset" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code>ZADD task:queue 10 "uuid-1" # Priority 10
|
|
ZADD task:queue 5 "uuid-2" # Priority 5
|
|
ZPOPMAX task:queue 1 # Returns uuid-1 (highest)
|
|
</code></pre></div>
|
|
<h2 id="api-server-integration">API Server Integration<a class="headerlink" href="#api-server-integration" title="Permanent link">¶</a></h2>
|
|
<h3 id="initialization">Initialization<a class="headerlink" href="#initialization" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// cmd/api-server/main.go</span>
|
|
<span class="nx">queueCfg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">Config</span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">RedisAddr</span><span class="p">:</span><span class="w"> </span><span class="nx">cfg</span><span class="p">.</span><span class="nx">Redis</span><span class="p">.</span><span class="nx">Addr</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">RedisPassword</span><span class="p">:</span><span class="w"> </span><span class="nx">cfg</span><span class="p">.</span><span class="nx">Redis</span><span class="p">.</span><span class="nx">Password</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">RedisDB</span><span class="p">:</span><span class="w"> </span><span class="nx">cfg</span><span class="p">.</span><span class="nx">Redis</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
<span class="nx">taskQueue</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">NewTaskQueue</span><span class="p">(</span><span class="nx">queueCfg</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
<h3 id="websocket-handler">WebSocket Handler<a class="headerlink" href="#websocket-handler" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// internal/api/ws.go</span>
|
|
<span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">h</span><span class="w"> </span><span class="o">*</span><span class="nx">WSHandler</span><span class="p">)</span><span class="w"> </span><span class="nx">handleQueueJob</span><span class="p">(</span><span class="nx">conn</span><span class="w"> </span><span class="o">*</span><span class="nx">websocket</span><span class="p">.</span><span class="nx">Conn</span><span class="p">,</span><span class="w"> </span><span class="nx">payload</span><span class="w"> </span><span class="p">[]</span><span class="kt">byte</span><span class="p">)</span><span class="w"> </span><span class="kt">error</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="c1">// Parse request</span>
|
|
<span class="w"> </span><span class="nx">apiKeyHash</span><span class="p">,</span><span class="w"> </span><span class="nx">commitID</span><span class="p">,</span><span class="w"> </span><span class="nx">priority</span><span class="p">,</span><span class="w"> </span><span class="nx">jobName</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">parsePayload</span><span class="p">(</span><span class="nx">payload</span><span class="p">)</span>
|
|
|
|
<span class="w"> </span><span class="c1">// Create task with unique ID</span>
|
|
<span class="w"> </span><span class="nx">taskID</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">uuid</span><span class="p">.</span><span class="nx">New</span><span class="p">().</span><span class="nx">String</span><span class="p">()</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&</span><span class="nx">queue</span><span class="p">.</span><span class="nx">Task</span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">ID</span><span class="p">:</span><span class="w"> </span><span class="nx">taskID</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">JobName</span><span class="p">:</span><span class="w"> </span><span class="nx">jobName</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">Status</span><span class="p">:</span><span class="w"> </span><span class="s">"queued"</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="nx">Priority</span><span class="p">:</span><span class="w"> </span><span class="nb">int64</span><span class="p">(</span><span class="nx">priority</span><span class="p">),</span>
|
|
<span class="w"> </span><span class="nx">Metadata</span><span class="p">:</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
|
|
<span class="w"> </span><span class="s">"commit_id"</span><span class="p">:</span><span class="w"> </span><span class="nx">commitID</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="s">"user"</span><span class="p">:</span><span class="w"> </span><span class="nx">user</span><span class="p">,</span>
|
|
<span class="w"> </span><span class="p">},</span>
|
|
<span class="w"> </span><span class="p">}</span>
|
|
|
|
<span class="w"> </span><span class="c1">// Enqueue</span>
|
|
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">h</span><span class="p">.</span><span class="nx">queue</span><span class="p">.</span><span class="nx">AddTask</span><span class="p">(</span><span class="nx">task</span><span class="p">);</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">h</span><span class="p">.</span><span class="nx">sendErrorPacket</span><span class="p">(</span><span class="nx">conn</span><span class="p">,</span><span class="w"> </span><span class="nx">ErrorCodeDatabaseError</span><span class="p">,</span><span class="w"> </span><span class="o">...</span><span class="p">)</span>
|
|
<span class="w"> </span><span class="p">}</span>
|
|
|
|
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">h</span><span class="p">.</span><span class="nx">sendSuccessPacket</span><span class="p">(</span><span class="nx">conn</span><span class="p">,</span><span class="w"> </span><span class="s">"Job queued"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
</code></pre></div>
|
|
<h2 id="worker-integration">Worker Integration<a class="headerlink" href="#worker-integration" title="Permanent link">¶</a></h2>
|
|
<h3 id="task-polling">Task Polling<a class="headerlink" href="#task-polling" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// cmd/worker/worker_server.go</span>
|
|
<span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">w</span><span class="w"> </span><span class="o">*</span><span class="nx">Worker</span><span class="p">)</span><span class="w"> </span><span class="nx">Start</span><span class="p">()</span><span class="w"> </span><span class="kt">error</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">w</span><span class="p">.</span><span class="nx">queue</span><span class="p">.</span><span class="nx">WaitForNextTask</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
|
|
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">task</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="k">go</span><span class="w"> </span><span class="nx">w</span><span class="p">.</span><span class="nx">executeTask</span><span class="p">(</span><span class="nx">task</span><span class="p">)</span>
|
|
<span class="w"> </span><span class="p">}</span>
|
|
<span class="w"> </span><span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</code></pre></div>
|
|
<h3 id="task-execution">Task Execution<a class="headerlink" href="#task-execution" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">w</span><span class="w"> </span><span class="o">*</span><span class="nx">Worker</span><span class="p">)</span><span class="w"> </span><span class="nx">executeTask</span><span class="p">(</span><span class="nx">task</span><span class="w"> </span><span class="o">*</span><span class="nx">queue</span><span class="p">.</span><span class="nx">Task</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="c1">// Update status</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">Status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"running"</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">StartedAt</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="o">&</span><span class="nx">now</span>
|
|
<span class="w"> </span><span class="nx">w</span><span class="p">.</span><span class="nx">queue</span><span class="p">.</span><span class="nx">UpdateTaskWithMetrics</span><span class="p">(</span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="s">"start"</span><span class="p">)</span>
|
|
|
|
<span class="w"> </span><span class="c1">// Execute</span>
|
|
<span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">w</span><span class="p">.</span><span class="nx">runJob</span><span class="p">(</span><span class="nx">task</span><span class="p">)</span>
|
|
|
|
<span class="w"> </span><span class="c1">// Finalize</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">Status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"completed"</span><span class="w"> </span><span class="c1">// or "failed"</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">EndedAt</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="o">&</span><span class="nx">endTime</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">Error</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">err</span><span class="p">.</span><span class="nx">Error</span><span class="p">()</span><span class="w"> </span><span class="c1">// if err != nil</span>
|
|
<span class="w"> </span><span class="nx">w</span><span class="p">.</span><span class="nx">queue</span><span class="p">.</span><span class="nx">UpdateTaskWithMetrics</span><span class="p">(</span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="s">"final"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
</code></pre></div>
|
|
<h2 id="configuration">Configuration<a class="headerlink" href="#configuration" title="Permanent link">¶</a></h2>
|
|
<h3 id="api-server-configsconfigyaml">API Server (<code>configs/config.yaml</code>)<a class="headerlink" href="#api-server-configsconfigyaml" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="nt">redis</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="nt">addr</span><span class="p">:</span><span class="w"> </span><span class="s">"localhost:6379"</span>
|
|
<span class="w"> </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="s">""</span>
|
|
<span class="w"> </span><span class="nt">db</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">0</span>
|
|
</code></pre></div>
|
|
<h3 id="worker-configsworker-configyaml">Worker (<code>configs/worker-config.yaml</code>)<a class="headerlink" href="#worker-configsworker-configyaml" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="nt">redis</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="nt">addr</span><span class="p">:</span><span class="w"> </span><span class="s">"localhost:6379"</span>
|
|
<span class="w"> </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="s">""</span>
|
|
<span class="w"> </span><span class="nt">db</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">0</span>
|
|
|
|
<span class="nt">metrics_flush_interval</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">500ms</span>
|
|
</code></pre></div>
|
|
<h2 id="monitoring">Monitoring<a class="headerlink" href="#monitoring" title="Permanent link">¶</a></h2>
|
|
<h3 id="queue-depth">Queue Depth<a class="headerlink" href="#queue-depth" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="nx">depth</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">QueueDepth</span><span class="p">()</span>
|
|
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">"Pending tasks: %d\n"</span><span class="p">,</span><span class="w"> </span><span class="nx">depth</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
<h3 id="worker-heartbeat">Worker Heartbeat<a class="headerlink" href="#worker-heartbeat" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// Worker sends heartbeat every 30s</span>
|
|
<span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">Heartbeat</span><span class="p">(</span><span class="nx">workerID</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
<h3 id="metrics">Metrics<a class="headerlink" href="#metrics" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code>HGETALL job:metrics:{job_name}
|
|
# Returns: timestamp, tasks_start, tasks_final, etc
|
|
</code></pre></div>
|
|
<h2 id="error-handling">Error Handling<a class="headerlink" href="#error-handling" title="Permanent link">¶</a></h2>
|
|
<h3 id="task-failures">Task Failures<a class="headerlink" href="#task-failures" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">w</span><span class="p">.</span><span class="nx">runJob</span><span class="p">(</span><span class="nx">task</span><span class="p">);</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">Status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">"failed"</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">.</span><span class="nx">Error</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">err</span><span class="p">.</span><span class="nx">Error</span><span class="p">()</span>
|
|
<span class="w"> </span><span class="nx">w</span><span class="p">.</span><span class="nx">queue</span><span class="p">.</span><span class="nx">UpdateTask</span><span class="p">(</span><span class="nx">task</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
</code></pre></div>
|
|
<h3 id="redis-connection-loss">Redis Connection Loss<a class="headerlink" href="#redis-connection-loss" title="Permanent link">¶</a></h3>
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// TaskQueue automatically reconnects</span>
|
|
<span class="c1">// Workers should implement retry logic</span>
|
|
<span class="k">for</span><span class="w"> </span><span class="nx">retries</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">retries</span><span class="w"> </span><span class="p"><</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="nx">retries</span><span class="o">++</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">task</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">GetNextTask</span><span class="p">()</span>
|
|
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
|
|
<span class="w"> </span><span class="k">break</span>
|
|
<span class="w"> </span><span class="p">}</span>
|
|
<span class="w"> </span><span class="nx">time</span><span class="p">.</span><span class="nx">Sleep</span><span class="p">(</span><span class="nx">backoff</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
</code></pre></div>
|
|
<h2 id="testing">Testing<a class="headerlink" href="#testing" title="Permanent link">¶</a></h2>
|
|
<div class="highlight"><pre><span></span><code><span class="c1">// tests using miniredis</span>
|
|
<span class="nx">s</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">miniredis</span><span class="p">.</span><span class="nx">Run</span><span class="p">()</span>
|
|
<span class="k">defer</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span>
|
|
|
|
<span class="nx">tq</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">queue</span><span class="p">.</span><span class="nx">NewTaskQueue</span><span class="p">(</span><span class="nx">queue</span><span class="p">.</span><span class="nx">Config</span><span class="p">{</span>
|
|
<span class="w"> </span><span class="nx">RedisAddr</span><span class="p">:</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">Addr</span><span class="p">(),</span>
|
|
<span class="p">})</span>
|
|
|
|
<span class="nx">task</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&</span><span class="nx">queue</span><span class="p">.</span><span class="nx">Task</span><span class="p">{</span><span class="nx">ID</span><span class="p">:</span><span class="w"> </span><span class="s">"test-1"</span><span class="p">,</span><span class="w"> </span><span class="nx">JobName</span><span class="p">:</span><span class="w"> </span><span class="s">"test"</span><span class="p">}</span>
|
|
<span class="nx">tq</span><span class="p">.</span><span class="nx">AddTask</span><span class="p">(</span><span class="nx">task</span><span class="p">)</span>
|
|
|
|
<span class="nx">fetched</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">tq</span><span class="p">.</span><span class="nx">GetNextTask</span><span class="p">()</span>
|
|
<span class="c1">// assert fetched.ID == "test-1"</span>
|
|
</code></pre></div>
|
|
<h2 id="best-practices">Best Practices<a class="headerlink" href="#best-practices" title="Permanent link">¶</a></h2>
|
|
<ol>
|
|
<li><strong>Unique Task IDs</strong>: Always use UUIDs to avoid conflicts</li>
|
|
<li><strong>Metadata</strong>: Store commit_id and user in task metadata</li>
|
|
<li><strong>Priority</strong>: Higher values execute first (0-255 range)</li>
|
|
<li><strong>Status Updates</strong>: Update status at each lifecycle stage</li>
|
|
<li><strong>Error Logging</strong>: Store detailed errors in task.Error</li>
|
|
<li><strong>Heartbeats</strong>: Workers should send heartbeats regularly</li>
|
|
<li><strong>Metrics</strong>: Use UpdateTaskWithMetrics for atomic updates</li>
|
|
</ol>
|
|
<hr />
|
|
<p>For implementation details, see:
|
|
- <a href="https://github.com/jfraeys/fetch_ml/blob/main/internal/queue/task.go">internal/queue/task.go</a>
|
|
- <a href="https://github.com/jfraeys/fetch_ml/blob/main/internal/queue/queue.go">internal/queue/queue.go</a></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</article>
|
|
</div>
|
|
|
|
|
|
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<footer class="md-footer">
|
|
|
|
<div class="md-footer-meta md-typeset">
|
|
<div class="md-footer-meta__inner md-grid">
|
|
<div class="md-copyright">
|
|
|
|
|
|
Made with
|
|
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
|
|
Material for MkDocs
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
</div>
|
|
<div class="md-dialog" data-md-component="dialog">
|
|
<div class="md-dialog__inner md-typeset"></div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["navigation.instant", "navigation.tracking", "navigation.tabs", "navigation.sections", "navigation.expand", "navigation.indexes", "toc.integrate", "search.highlight", "search.share"], "search": "../assets/javascripts/workers/search.7a47a382.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
|
|
|
|
|
|
<script src="../assets/javascripts/bundle.e71a0d61.min.js"></script>
|
|
|
|
|
|
</body>
|
|
</html> |