From b469608d0de8570dd741c9739410386f3f329542 Mon Sep 17 00:00:00 2001 From: lynnagara Date: Tue, 21 Nov 2023 16:59:11 +0000 Subject: [PATCH] deploy: 03697f3d9b03677eb99c5f2501910017feb8fb75 --- .buildinfo | 4 + .doctrees/architecture.doctree | Bin 0 -> 25729 bytes .doctrees/backpressure.doctree | Bin 0 -> 7799 bytes .doctrees/dlqs.doctree | Bin 0 -> 29691 bytes .doctrees/environment.pickle | Bin 0 -> 627749 bytes .doctrees/getstarted.doctree | Bin 0 -> 22281 bytes .doctrees/index.doctree | Bin 0 -> 5231 bytes .doctrees/intro.doctree | Bin 0 -> 4392 bytes .doctrees/metrics.doctree | Bin 0 -> 39885 bytes .doctrees/offsets.doctree | Bin 0 -> 8000 bytes .doctrees/strategies/batching.doctree | Bin 0 -> 25670 bytes .doctrees/strategies/commit_offsets.doctree | Bin 0 -> 6657 bytes .doctrees/strategies/filter.doctree | Bin 0 -> 15369 bytes .doctrees/strategies/healthcheck.doctree | Bin 0 -> 14329 bytes .doctrees/strategies/index.doctree | Bin 0 -> 102132 bytes .doctrees/strategies/produce.doctree | Bin 0 -> 11964 bytes .doctrees/strategies/reduce.doctree | Bin 0 -> 22838 bytes .doctrees/strategies/run_task.doctree | Bin 0 -> 9793 bytes .../strategies/run_task_in_threads.doctree | Bin 0 -> 12803 bytes .../run_task_with_multiprocessing.doctree | Bin 0 -> 49169 bytes .doctrees/strategies/unfold.doctree | Bin 0 -> 11082 bytes .doctrees/what_for.doctree | Bin 0 -> 30633 bytes .nojekyll | 0 _images/arroyo-banner.png | Bin 0 -> 71723 bytes _images/arroyo_processing.png | Bin 0 -> 19166 bytes _images/consumer_groups.png | Bin 0 -> 23512 bytes _images/kafka_producer.png | Bin 0 -> 16532 bytes _sources/architecture.rst.txt | 120 +++ _sources/backpressure.rst.txt | 43 + _sources/dlqs.rst.txt | 21 + _sources/getstarted.rst.txt | 226 +++++ _sources/index.rst.txt | 16 + _sources/intro.rst.txt | 15 + _sources/metrics.rst.txt | 53 + _sources/offsets.rst.txt | 37 + _sources/strategies/batching.rst.txt | 10 + _sources/strategies/commit_offsets.rst.txt | 8 + _sources/strategies/filter.rst.txt | 5 + _sources/strategies/healthcheck.rst.txt | 74 ++ _sources/strategies/index.rst.txt | 38 + _sources/strategies/produce.rst.txt | 5 + _sources/strategies/reduce.rst.txt | 7 + _sources/strategies/run_task.rst.txt | 5 + .../strategies/run_task_in_threads.rst.txt | 5 + .../run_task_with_multiprocessing.rst.txt | 5 + _sources/strategies/unfold.rst.txt | 7 + _sources/what_for.rst.txt | 276 ++++++ _static/arroyo-banner.png | Bin 0 -> 71723 bytes _static/arroyo-logo.png | Bin 0 -> 13031 bytes _static/basic.css | 921 ++++++++++++++++++ _static/custom.css | 10 + _static/diagrams/arroyo_processing.png | Bin 0 -> 19166 bytes _static/diagrams/consumer_groups.png | Bin 0 -> 23512 bytes _static/diagrams/kafka_producer.png | Bin 0 -> 16532 bytes _static/doctools.js | 156 +++ _static/documentation_options.js | 14 + _static/file.png | Bin 0 -> 286 bytes _static/language_data.js | 199 ++++ _static/minus.png | Bin 0 -> 90 bytes _static/plus.png | Bin 0 -> 90 bytes _static/print.css | 29 + _static/pygments.css | 63 ++ _static/searchtools.js | 566 +++++++++++ _static/shibuya.css | 1 + _static/shibuya.js | 1 + _static/sphinx_highlight.js | 144 +++ architecture.html | 321 ++++++ backpressure.html | 249 +++++ dlqs.html | 283 ++++++ genindex.html | 551 +++++++++++ getstarted.html | 427 ++++++++ index.html | 228 +++++ intro.html | 205 ++++ metrics.html | 366 +++++++ objects.inv | Bin 0 -> 1299 bytes offsets.html | 243 +++++ py-modindex.html | 210 ++++ search.html | 154 +++ searchindex.js | 1 + strategies/batching.html | 293 ++++++ strategies/commit_offsets.html | 235 +++++ strategies/filter.html | 248 +++++ strategies/healthcheck.html | 291 ++++++ strategies/index.html | 559 +++++++++++ strategies/produce.html | 241 +++++ strategies/reduce.html | 269 +++++ strategies/run_task.html | 232 +++++ strategies/run_task_in_threads.html | 239 +++++ strategies/run_task_with_multiprocessing.html | 353 +++++++ strategies/unfold.html | 238 +++++ what_for.html | 482 +++++++++ 91 files changed, 10002 insertions(+) create mode 100644 .buildinfo create mode 100644 .doctrees/architecture.doctree create mode 100644 .doctrees/backpressure.doctree create mode 100644 .doctrees/dlqs.doctree create mode 100644 .doctrees/environment.pickle create mode 100644 .doctrees/getstarted.doctree create mode 100644 .doctrees/index.doctree create mode 100644 .doctrees/intro.doctree create mode 100644 .doctrees/metrics.doctree create mode 100644 .doctrees/offsets.doctree create mode 100644 .doctrees/strategies/batching.doctree create mode 100644 .doctrees/strategies/commit_offsets.doctree create mode 100644 .doctrees/strategies/filter.doctree create mode 100644 .doctrees/strategies/healthcheck.doctree create mode 100644 .doctrees/strategies/index.doctree create mode 100644 .doctrees/strategies/produce.doctree create mode 100644 .doctrees/strategies/reduce.doctree create mode 100644 .doctrees/strategies/run_task.doctree create mode 100644 .doctrees/strategies/run_task_in_threads.doctree create mode 100644 .doctrees/strategies/run_task_with_multiprocessing.doctree create mode 100644 .doctrees/strategies/unfold.doctree create mode 100644 .doctrees/what_for.doctree create mode 100644 .nojekyll create mode 100644 _images/arroyo-banner.png create mode 100644 _images/arroyo_processing.png create mode 100644 _images/consumer_groups.png create mode 100644 _images/kafka_producer.png create mode 100644 _sources/architecture.rst.txt create mode 100644 _sources/backpressure.rst.txt create mode 100644 _sources/dlqs.rst.txt create mode 100644 _sources/getstarted.rst.txt create mode 100644 _sources/index.rst.txt create mode 100644 _sources/intro.rst.txt create mode 100644 _sources/metrics.rst.txt create mode 100644 _sources/offsets.rst.txt create mode 100644 _sources/strategies/batching.rst.txt create mode 100644 _sources/strategies/commit_offsets.rst.txt create mode 100644 _sources/strategies/filter.rst.txt create mode 100644 _sources/strategies/healthcheck.rst.txt create mode 100644 _sources/strategies/index.rst.txt create mode 100644 _sources/strategies/produce.rst.txt create mode 100644 _sources/strategies/reduce.rst.txt create mode 100644 _sources/strategies/run_task.rst.txt create mode 100644 _sources/strategies/run_task_in_threads.rst.txt create mode 100644 _sources/strategies/run_task_with_multiprocessing.rst.txt create mode 100644 _sources/strategies/unfold.rst.txt create mode 100644 _sources/what_for.rst.txt create mode 100644 _static/arroyo-banner.png create mode 100644 _static/arroyo-logo.png create mode 100644 _static/basic.css create mode 100644 _static/custom.css create mode 100644 _static/diagrams/arroyo_processing.png create mode 100644 _static/diagrams/consumer_groups.png create mode 100644 _static/diagrams/kafka_producer.png create mode 100644 _static/doctools.js create mode 100644 _static/documentation_options.js create mode 100644 _static/file.png create mode 100644 _static/language_data.js create mode 100644 _static/minus.png create mode 100644 _static/plus.png create mode 100644 _static/print.css create mode 100644 _static/pygments.css create mode 100644 _static/searchtools.js create mode 100644 _static/shibuya.css create mode 100644 _static/shibuya.js create mode 100644 _static/sphinx_highlight.js create mode 100644 architecture.html create mode 100644 backpressure.html create mode 100644 dlqs.html create mode 100644 genindex.html create mode 100644 getstarted.html create mode 100644 index.html create mode 100644 intro.html create mode 100644 metrics.html create mode 100644 objects.inv create mode 100644 offsets.html create mode 100644 py-modindex.html create mode 100644 search.html create mode 100644 searchindex.js create mode 100644 strategies/batching.html create mode 100644 strategies/commit_offsets.html create mode 100644 strategies/filter.html create mode 100644 strategies/healthcheck.html create mode 100644 strategies/index.html create mode 100644 strategies/produce.html create mode 100644 strategies/reduce.html create mode 100644 strategies/run_task.html create mode 100644 strategies/run_task_in_threads.html create mode 100644 strategies/run_task_with_multiprocessing.html create mode 100644 strategies/unfold.html create mode 100644 what_for.html diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..fc936790 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 9db9da0647afe63ce71f2b065b7306e5 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/architecture.doctree b/.doctrees/architecture.doctree new file mode 100644 index 0000000000000000000000000000000000000000..90a3016abb986181e57a11bf579d448a6eb72fc8 GIT binary patch literal 25729 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 literal 0 HcmV?d00001 diff --git a/.doctrees/backpressure.doctree b/.doctrees/backpressure.doctree new file mode 100644 index 0000000000000000000000000000000000000000..59223eb20d4ecd64a1628a3b2c15e3c64d47ae87 GIT binary patch literal 7799 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 literal 0 HcmV?d00001 diff --git a/.doctrees/dlqs.doctree b/.doctrees/dlqs.doctree new file mode 100644 index 0000000000000000000000000000000000000000..4efc44a2fdd6be8450e58c42b4cde1f38cfe01e7 GIT binary patch literal 29691 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 NB?-D=&&$2B{|DsE6rcbA literal 0 HcmV?d00001 diff --git a/.doctrees/getstarted.doctree b/.doctrees/getstarted.doctree new file mode 100644 index 0000000000000000000000000000000000000000..be0a912275b3f32ea05b0b5e056f522825e1f8db GIT binary patch literal 22281 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 W#Xp1MhuJ|)k+2RLR5X^O;XeUngweJD literal 0 HcmV?d00001 diff --git a/.doctrees/intro.doctree b/.doctrees/intro.doctree new file mode 100644 index 0000000000000000000000000000000000000000..4cbdf306890e48354f9bf1c985fd34b0c6fb02a2 GIT binary patch literal 4392 zcmcIn-;W$e5w?BVz1zLJy&tio0I@VkBsrVhE;3k3PKv;a07WPK5D+Lrr*Y3r&vt8P zrYGG!zS{>2B4HGxeoOO+5dQ;0{BOMQ)y(Yd?i~rf7*1NC=eq|t z>OZ$3Rr(2LD8?}p4;Eu+f9Q}S#>CI()(%{XJmK#1>N!Sd#7E2+xmAY$=M z^R!u08}e=gmb~jXcD%dw!9&O@Exr5JS2_wWVpb$FVT~8==6x@|Ybv*C*_6zAF?9Ws z0U+zeh8u((q8RlTKt7xZmGgGFfo{xQfKU z4Pb>$H7ms`+`oNPV;e{luppC>W_li26+{)TEihJdmdj!qu(Hf#jN4F!39Mi?i1CHH z4^pl2A?3*CFcxsb64q%}NC+s#AFKcNLlv!?;(NIY-{R}A>&F+N;9 z24LK?(q=paEjj3d_*%pqJUzJLSOfk8w|B|o6$3wCHSqN~{S^3o2y7m>qnADLilOzB z{H()wXBCx&!^0&~D=I$yCcfSruV`3vg1;0iw*Dh4j@ys{-=9jP!60X{$PhI`bA&@x z#1thglNQ7|Ssd${yOuQg?B!3sVDt8h-vhTDRawSum`S9BC1*sRvg8qE2AT<_<@w6A z`}k2{xD8Yqun2j8)u%FnEKDgiPbkb|mFM6#GN@tGD_NpM{^hzbZ64^tN_;_vL8bqp zg(X~nx;|XHfa{O{EmQmfi#~63Q^ug2`n)6ZPkxE?yp9v#F)~NeOy|HbB`9-N;IX6U zGN62^dBieS!~pIJM1O4|dUeH1Wd3%2WJWmjUtS5BA3rKU8BiowcvvE>W?ZiVMKtPg zI@gF9JT_G!ZGZ>UUggd|T3}vT?-G}PULTh|;PUtD_@1`5Ym8K#jY;`?$ zI}1ruL%1zam~IDU-$7T#;qfmlFA~&6zh-zBO_xDjUsblOtbgo!^}~ga!IYzZVOD7x z)HRW1d5OVxV-`88m|-|308SG zsBC)t{;`qxertU)#?|wEy$1G{=tuc=SZjVCG{j(s()vp z9+Aq3ugKkF$!%KOKn|D)n`baKuq;9dp&j$5Tkb9hnTK6$cJ*p#N@Bz=+dBRlDrFC`l31h4YMQWjD9-PS|o*;hba6xcxVdPGXRkM(z z{>wr%#guDnw+~1&T{$%YO-_5^HhA%rS~0iPm)c6ar9>h-&^q-Gli zp`(#d6fV{^j;%_Xb!ULa%=1WP-Hq2vZ(kC2s|RZu2Meq9ro%P;$fnv-`o42nS385J z3^^iJ6=eYLwqu1lw<%L`{*PMumpJot{|Wex1{jgkRI5#h9(Ji>O}yQS>r2{}MVwU$ VB2-Q3eufEUvo`Rlc&MWBzX8u?nHK;6 literal 0 HcmV?d00001 diff --git a/.doctrees/metrics.doctree b/.doctrees/metrics.doctree new file mode 100644 index 0000000000000000000000000000000000000000..932cf45ec8e2ad781efbd5eb00d857f07870dfb0 GIT binary patch literal 39885 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 literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/batching.doctree b/.doctrees/strategies/batching.doctree new file mode 100644 index 0000000000000000000000000000000000000000..993fd922d1b02cda8e854e51d1ca65418e01bc2b GIT binary patch literal 25670 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 RC>E{ULMP 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 eK2!!@EEcH literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/healthcheck.doctree b/.doctrees/strategies/healthcheck.doctree new file mode 100644 index 0000000000000000000000000000000000000000..cc69e6c6cfe487857749d5a2f064fd4412183700 GIT binary patch literal 14329 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 P;4O~~MyXqM5ZC!H6=g(I literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/index.doctree b/.doctrees/strategies/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..eeab2bcccf3cd4eae8f07427470b27c2684b1eb9 GIT binary patch literal 102132 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 C?1b3> literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/reduce.doctree b/.doctrees/strategies/reduce.doctree new file mode 100644 index 0000000000000000000000000000000000000000..9168159b75e0879581376fd0c01f039259253ffc GIT binary patch literal 22838 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 literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/run_task_in_threads.doctree b/.doctrees/strategies/run_task_in_threads.doctree new file mode 100644 index 0000000000000000000000000000000000000000..96622b19db1494b1f97abc150fd29a1c0ea1996f GIT binary patch literal 12803 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 X9a^D59@3>KH)l|2PoiLa4b=J%iuJ`{ literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/run_task_with_multiprocessing.doctree b/.doctrees/strategies/run_task_with_multiprocessing.doctree new file mode 100644 index 0000000000000000000000000000000000000000..fa60d009185b980781de9014ef4bb075e4380d8a GIT binary patch literal 49169 zcmeHw36LDuc^($PE_Mft#X%Ax34v^yqOqWNXCp>dXz;LjghwDkEE0?$GN{>}nV#*Q zo#`G=_h7LIsnE9U2ua74q9!U?xfCC=%CcFBDy2%wN8}1)E39%3yW*&lII&rd%aIQpxwfqx<#io;N)+OG>oKDgu~3{`cRdCY-;iUx(6fPGG<1*0OSOa`_dvWL=(rFc?0CL2yfCQSam9|J zzE>Yapr7bH;59>{?NFm*haoQF-}AoR<^Ni24tnX2y4~3BJ1u%<5Fd){ExI*ykGiMa zW%u3g0rzx#X~PY=&PIRW`%ZsjC+Kf)*!_O68_2(aV7S2%+X$n+9XVT`6VeN{2%M=A zXKLLnXR7@W0DL#%31E-4szT(z`{H6|6Tb14E{e$q=7qq3<9)Q zks3HyFqi%aqhD?cGXl2)fB6$5vyVR5C^h80}OZJLNv4o?zg$?DHkuew?S5J zm8+!GsgeXPkS;;*;!S89Dcgs^QBBpXRVHoA^Jk#{>@a?AddjP#u^XD0vM)Xe({1F$ zzY5J*p*ywEgI-31zG`}xqW$~!jUI8eHSn1spR+z1?e@UH>LYfiW7j**3om?B5Q!U3 zSbYk{YHvB()r-$^Ro;Et-t7c-^YZ02OTIUSYE>^jk0L-sMR6FGgSDR8x390S>C1uCk8ZcPyDgy*1K(VEq@uh!~z)Nmn|YfkQB z$+P)t|wiYttdtSKz&IocoXPseodFH`2>wc-rwXkP5z@+36 z>&$}>!n3g`b26T1Zwy5+fDd_|dt%{36rKgVL!GM6?I4T_L5xp3#>`;0bhwlpcMnP8-1{^)2iuf~Vr zMb{xIhJSp7$YF}cemkmg-Cg$@N%F;1lI~weu;z?dVvNwaaO-GSEQvHdlG5;ZO*AYL z4V-{QLSr=UKTwGK35GkeE65NIv*RHPNkw_-5<<#5af5QZX|ktx;s(zyisOcG@6vlG zI;iMhd~d3JX|f{IlcIz~CKU;AX4aH1)pP@0l(3~arWaDPW%L{>~qXL z-pDMA2JTVfHONK8xpQ)0{3{*tUztYiSS4MY zNCL|}$8RDe)vlthQiLl?nv?OO6s^LAHw?(CbIRbj1L6$ z_7Jr$e%t*mCmO~_wY+y2AI9CV=QO;Q*BD-pmk>gEy)%r@O&`T50oXmqla>nAdm$123kunPY9RadoQz2HWx%!%&F$Ma735!+2q(fiBxIi=-M+~TeT2B& zuPL$;8D2(OHwpn{Y7&#k+&`I?@9n$IB#dT#oV;i z;06^h#V?+PyGWleD};Q|Ovq?{DHc!+`T0G7yq4J3nu4=CE#z^YwSC15x!Adq;pVmH zkO*K3-XAkVpGs*Sp5D31q-JJIESCSL%+!w5EUhy8mpNxCBD40K!abSfe->W#haj9E zlfEy$SDBzFn0d(0HE3B#8bg;7NK!?WD@hK}{-T))g~YYLfS0l{rZB;1zh(wr$YBY5 ztSS7G8F-;7NZ=`()~Dfe-k470!60?hC+a%A%YVoaRQi`=WFOV0d zk5`M z08azY0Ziy~CgqKR-Ah^ZBjy1W36>8ZY>0`y+GiO5vy<4aNmSD)+YJS)964=U$v!02 zO~0Hn@yli=78CIrqgO4aixZt+F#|8wHvxRCzWs(7c(J|-;8W?_ADah!3-#^mjQ^$d zjT1bLzTK3nlCpqi(l~moK;ziuRO4V_Eg88RKGB3E)aAA@kjrBJx*50;^SmGrQsaP91bxK}y@Vv)uVKe17aWe~-jXsb zxRdhWJ|hoCuV!27?dU9SB*oA2nK=#OC`Y=1b){zN_$NwWW49+C}`4D zbZNBbKSR~1p5(Jm&ulMb&iUV1^rH0t#W&LsaB$uf)<=YZeR!!%2smK|UhEwN@Uec) zG6OGGashm%5O9xqU`5z(b_l3)IgDl1V`hwtStWpv4FMO;z>9@k7W29pxDoU5A)sf5 zUP6+469PClG^bG<0?Jy)-!hX{%s39bR0#N#5xy}5lqKP_#vw+806{|e5b)29qf8S5 zI0~9H6cptY@}J$;RauUNE+}r@rj4^12KFnQN)r|D=)X5pMq#yi~^R|A-lQ zu}2WV$NI7_n1L57wg8^8>Xwnr6-8Fwc@#8~w_h_OqX>OeD9{|pBu(Un9k%T+<%Cq+ zx%Cw@>cv7T3;Z|t26%B3=O672@Zvt+{fCU9(#V#vx_itFyjXVy&+`hYuX@~OhCaD6 zPPyulSCV2m-ebmhHdcSY4BW`-u_@05Gw|6k|7&L8M$E@6N!twlEmjgONEW9&Wh2AK z%%l}Fjsq{1^1Nb%Z%ld0lJFVh5F=6^K|=YI=T+k<)1*8c1x=cYE@>%``N8-Wc6vpP z7WHb$#y$MR?onE5b3cO~da>nMZj@CZp10}z3Y^P<-EqUXLR(m|R}06C3^TiK-Gvyt`#K%A2he>buGFHSL6}G3u>H%#>{q@Yd&SsQ@eGmijC-1+4{|<4O`yoF z_QibTb0hF0^;8vkgasXovP3-D>f1e6UA%n|JAy6SlG_gHWD0t&({VbM-RK8lXm$C? z3!ycj6E3W9P!}7)aVmq%7iR^NrkMZ3sAcK~Xj(q~ReJh#{AXhaJC?rxi=ci`Z~u4v zGg(*ZY#L4#+1!L^oY0C~$J*S~&TzraFlu(Zy2TaOih>HxtMJ2C(C??Zb8WQzt5>k2ygK2Q_GQH}`th;NF{f#PxOSA`C0}9R;Lz7R<*=?1&Do zVdS&ZaD>(1^q78tuznD?XTW`Gl3FTCgHr-L} z0fuu|If7D@bQmRc@KpOzhLYJ*9_HA8CwsL02>z0m$~7-5lqZs%YL<|Sh(s(diIaff z;7B+-cE6bl$Z4joE((OK+87vLhr1 zVZ?o!>mlW{{oT}H>JIG5vA(6z2`B^n7UYZUXsJR$>H8{#r1Z-vZ@#SYwv?z|8!0Nf zqlxOF35a~-<$oZ^eB3 zRoR41b_8zLXrlI#P~wN0Z|@gB-_EmGM#mA6W zICjHT>Z~;gDs*w!Bn7c<(BHM{gI0^VPxPy2Pi3=Uy{O)T1`c>^R*|{jH|t0RgkaEV zLIud&JB}Sj6;au-L*J~swKL%FGs~>DTzBTAottWjvWk;2U9Rdf8 zRuQ{y>99S1cBT20$SQYHj6c-?2x5=P4k*S+WDOeD>3R{dNJletB8o)R8qN_dY0TR6a_YMpnS9+lNy&&Ly>34ajTkdp;cz}*Tl zvJWfvBfDd@9CnDJW#jPg?l5o~23d}6(18W4^s|FJ8K)rC$uzvV-?<@}A* zP;OnyT3{)IK8cr#^H92@8gw?b`;Qaq{pO}F7Zke0)3Un1X;l8rtoCOfX5)<4e^C#d zj5j7EO({Fqbe?5u*&Bhro|oz?$uZtg_{*xW3L0g0(Tz1K)9 zg6(U9&CW|bu~+0tt9W!TxTT!}jzyqQD^j~kTmKk4!m(S4J` z`zDX?`9Q+_+c$lL$4tSyMv$k7?G;UI?Tl|);Ea$uqc07AT6@_nbKx*)L?-hE&fn6= zoXAT;B4!F^KQR-MpZTU2c4{TMEGMy&lNl>1@#d-a4NQ<`nNKtqbm<8k`;+TArK0Cq znvK9@5Jj%SN(VEpEWHk~_t2@}AY<&b3#--#y={k|>Cdu3t7%6z*E(Z)VFi9gmINrS zd{i*(to+hP(2L@N(^6Djcz&brP(qIiLqk$IXq%(TE2M_)Q*EY{A5>1@9AKPC0NSFPW_r#*{m3psd!q2A;ARpmIy8s@V%QyjK0+n%@Q-gf691!Tmx#BgGdSp z6DEgSM-yBc@iAG;oiibL+Zc|g`l54p5`DQNqc0`iJk|aWOqI>to+up0gQ9(a6poQr z<|7UzN<17jNrw1^ScM4}zkw4;g0OuLYHI8x$tN0a#Cvw~2?Dd~@8 zOR1BaMLbESd&Vj8-_dX|lO(*VjuDlFqoj~>Pk*bFlJyw(%veq4eg0V4c0f+&p-hVf zzQ{rA6jTt@@ue!?rzvh!2-?y}^;xAG4IdXl0!>TEC>H2@R!~Ivr`@Eoz!zYWG6P+1 zNY5)``I$wfT?PPGy}pCh2;bSUp56r%-@>UtP9I<8z@Ml(J`xNto4@5o){c$ig3wUa zca%LC)^0H9TaUJFe+%mYJ({Rz=j>awkWy$4ncWt`2r}1F;eBBuJrSz^Dia>GBj@bs zj;i|EN%{9rCli?hPWyUF?Q0r(X8q&MfO2y3ZiHA#o}QBZv$v<(K!R^W%u{jx(hTBU z%ZRg-&-y%5d$Z1De3lvN1GFN2s(r4+Qt-X}QEFc^eV>UM_U`15S|y;~#vheEqV8$& zt*OIutwDC{9g`R08!qGu3<@U23E*m{l%l z2&5()J32${9$P^`{ToPS8913fS}q!BtPtOCrRiPzL?7B-@bN(}+O1j-BZoy@-F48i zk9Xm%*z}dn_F`;qV!-s^ENi!961! zu-+8X6|Hh#U{2Cj+g zK?`3KWM4YQiGys56K$c9w=)g6xGlcii@e0G0CJjXC;{Cyq#KJ5(*MQ;VVtgxs;DADd1w4W)(VwJYaU>1YjW^HY- z9_qPLFH`3u_xYlAF4}QmS54L_8}x7+4O^J}LVqlxLBrv-AFQW04rMrcb6SOb918hcY~-mGaC@&c>kfDQhKpT!-ZeHQdloBFKJ9SDT!4+v z`UvhXWHlQa>(Rl1=5ut+Qv$(y+A;TgQFgIQ;H-ZHft}XF_bGT(OAgxC*H9DqSVW^K3pT-=r1eN_s1#vy8A$#U zXco^q*h~koq%54{Qen7sZ8Y4|d^sk(QHkIq>p%&Kj2xK~rWREbXvY`&{tknoDQ^yg z(@1f0Icu0^6U$D4JZUhFWf%tvzRgWN(o-$l>Y%V(g^qas8p=&ptx{f#nKGCLDK=a0 zV8t*^n6aWV!s^FaUdhtRi;E2vq(k{c6Wckofkh0#&=ndw4}|w~$$c(j`-Zg|I@omQ zT#b->|!U?qD)0lB7u zG>cTYcEW?D(a#hJNL1C+ib%n2EV+7-l#rXfp@4jFCUWPQNEL8q46zA9;k(c)iQ_T- zmIC(anXvTUGSyX3Hgh6V;c+FGd{8Ppx}kuq&%}kfssc*KZghyx7dRivIIi@~c#%mE zZbg~AP_K=hvA|4$X~yE_Cusv6D^z*gg4kP^oMtfkfz)Mx-y}?AGaBEMydh^ap3`SE z&VB?d8e)Oj+NMopi2u$m7O>eo0@8rY`~h;n3EoI?|3rdGnY1$-ZaxgDNlL(GZ0B)M zFwz%7oDpYCtY!<5z1{VYEk!>^grOA8`0uv73U=-F4vC+fh?Bz0|2SS6)Xf1Q%k+7Om}mZ%1QIKgUEHMqyUpIIqm?YP6~pro!_Sv^ ztF#!VT{c87dSe^CDPf2OCrnl{pPvyz{MfWLZx%F%tWNB-e@}=Pf|MUjop6J$I)oBT zet#M%{!R&bWTp55r1+a9-ZDrr4OaR*Uc5-|Fxu@o!*~J5QUXK=KY8k8!p|B&ErZ+&64G08v@@5EA}_D(Vktj;xX5s3wx`wv-bg5+{#C+Kg3jS=gK4I?VD*>WAF^I|2z ziUzXf4HWcgNtrJ^VwQp?IQ$knjjdXF*uh)}*kfM_ye1pb-`%lyN0v7yj%3TrOn8iM zmf5tfQZkdgkr7eN-d61PRt>y4vI*}?II&XaZxW-w2{czB$jq;)w_vZ$#HUC0z>G@M zn5iqut{go$6MearBeN7T7?!Pko}LNA|NH0Lxuo@jE}7BcFkkguR-&CA;_k{$SMlO( z${1H+(dF)z!xyLThVypVUO}tX54xFUVTcv8wjl)}){Vge6??3rt{#)er6;;J9Dh3F z3h&i$2R>GatJa4Gksd-2fOgqoA1r3@p(xDBDo^@w3O{`I8NrTIt_M-t1IdFZ^USn* ztj%M&nto>;{Vmeb=NKzJ{Y~7{Yxfne(bEPfMe7Cf)V;hPc~z5UR!vSyKcb?Sww9dWPDH(_Xy6w$ z(4{;G;ln)0KP3o}fr)XLG@=UB;mwG}pj@OjbCUrU{vB^%xCet_L zn^|?S4g*-{(Py2n1E~#c{27KeexmMGh@GVcEyO#p|0Ii>y>Pxym!xJfQ zes>a)uvy{XO5TvO!hJn0YQkBiRWnM+X5fV6Hdq0P?l)>;rG?w8ROV+A5V<1?_sE|x zCMU-r;EjG5v85NvNRk>}GM84+*%~-O$2Lx@k7^T>2>gBmCS)6_Xv37qU)U&o3n+V? z`AwW~C!6r$*5v9sRr|@ZI}HO@MeX?F1UfMCeg2?&&f4!_=<3V zxeH7+1Sri>rHi_mI0aYS1co0p@jHRD=+`+B4#}k)yuA@BlRrqM&`vS{1`bz^2G376&LLp%%P#VX|UzO z??XZP1!!p<3F3fnq0NLdT1up|d>h-HfOgm7jEpeEL7s4vbogWtY?HrCrXGVg{Y1sb|vpI*Dg`5uWLNOk!r? zmiA1)qG)H~M1XY7T9U~!Fl18XX0W&3x#FQ}w$Lw(lS1I9uyjHDt|qNUw4a0S}tNo7!)Q_D=W(L%5sTpBhukYjm0v-=TAiM*>6mIZmo zJDg$Fc)Cjbt`TaYq$dAJv+S(Pm}w&Lvl{49PJ{4aPUDe1(Av^;9?9spoDeGfRLsAa zi7Gp5JFMeZS`U8gf&G-Gd5ZbS*Jq;rW-2cVEje|xx;jqcXulVZ_R~y#%$jD%mqriQ zK7#3s_6q%RlqND3+Q;bM$MJ{KQN!_E!g+59tG<(FR@PP&bq9ululTB zi2QNEOl65_P)sh4rh-uY3VlUPd}UC6bx?n2HQwLb9meyGjva>jw-TH9N`mJP+y4)| zjt}8`imVx`z3(V~E;gO8q5MANW3sR5TpeDIm&HGk(Dirm`=}q#JU@P7f|FeWcJ5Pb z`_d_QSssLv60_>wAD>3ayB^u$_Bu^`u4_v&z*KxajXj768E&(UKl<8DZdbH>fNz^} z*YJV0{ifbcG#7;rV?r|1KY%ahmu! zAR6c5mBye?Csox1tPAn7yh6J%h8N;R6y>z>A{@rYn?YlMexk67ESVVAM8nx%wL6&k zOjbqX1)g;eFSti9#7lew6pqyeq$Ql6i&Wk2_VD8{ACSJMxs9I{@pI7c;MWoQR3)1@ zz+DVH&*c)IXazxp=#Nk?G{lt^vS|jMvDY+p)p5j-W4m&qD ztdZ1eOsjxAMieiQnz0MZeW!;VTeS}Qy1>5uamBSe$4W2hDn1+UE?!==N%f3WBlh0y{Cyw>u=dqwESZ01|(CsTVqfW>CA@C6zjc zW;z_ffx~?;zc1coTGEJWSG>^UDtffm^g=ol8H5Nd4@uL2nJt4DG}QUb&H(g?c&vt< zY#6D z3L<8iuGFztutvra-|R+FFFd!gfy-gF$4-!|2K}v#VSE!k$q>MkHGG8-;)x)RMOo2?y{9Ng`8X9=Il7jzM37!tSCY9aBnI4`Kwb&SN02^-9?O?E_$gabRnvpv^zZjo} zPIhaFc_v@nsNujoXvp>W7&a$HI1quR5<9fpYZxEw(Dw`DWqh^=hW1?p*mVd--N1hH zpEdf_kYMfU20l_`w#T>lN)6>5u#cLD_ z=iQ5($8=5^=P_+0<~*itER4r&@n{eqQ7wgu?g-A~;o%$N4pIuZYq4ZHj1M<(^a!*X`iqc# z=n=k@3T=1^mB2G_Jvb8+PE0NWkheUMc G)&CC&%h|F3 literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/unfold.doctree b/.doctrees/strategies/unfold.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a927401c3d82eebc854c556b71d68ce47775ffff GIT binary patch literal 11082 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 literal 0 HcmV?d00001 diff --git a/.doctrees/what_for.doctree b/.doctrees/what_for.doctree new file mode 100644 index 0000000000000000000000000000000000000000..5ece2d408154ffbdae892b0ff87a15fe22d1347e GIT binary patch literal 30633 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 I$s4u*2SM{!5&!@I literal 0 HcmV?d00001 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/_images/arroyo-banner.png b/_images/arroyo-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..90482cb669dcc531ab025eb4e1c7afe9282381b7 GIT binary patch literal 71723 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

#M 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

?H$}{j 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 o$bt4xlA4 literal 0 HcmV?d00001 diff --git a/_images/arroyo_processing.png b/_images/arroyo_processing.png new file mode 100644 index 0000000000000000000000000000000000000000..21004ddec1f5b65e4d272411acb2bff5724232d2 GIT binary patch literal 19166 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 literal 0 HcmV?d00001 diff --git a/_images/consumer_groups.png b/_images/consumer_groups.png new file mode 100644 index 0000000000000000000000000000000000000000..09aa7440e8124155500b3f926c49c8331a2f22af GIT binary patch literal 23512 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 literal 0 HcmV?d00001 diff --git a/_images/kafka_producer.png b/_images/kafka_producer.png new file mode 100644 index 0000000000000000000000000000000000000000..53a90d9d95a203732b2380077dc2e9646a1f5db8 GIT binary patch literal 16532 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 JE0NIi`5%ZO4Bh|$ literal 0 HcmV?d00001 diff --git a/_sources/architecture.rst.txt b/_sources/architecture.rst.txt new file mode 100644 index 00000000..0fedb49e --- /dev/null +++ b/_sources/architecture.rst.txt @@ -0,0 +1,120 @@ +=================== +Arroyo Architecture +=================== + +Arroyo is a set of high level abstractions to interact with Kafka. +These are meant to help the developer in writing performant consumers with +specific delivery guarantees. + +Common problems addressed by Arroyo are guaranteeing at-least-once delivery, +providing a dead letter queue abstraction, support parallel (multi-processing) +message processing, etc. + +The library is divided into three layers: the basic Kafka connectivity, the +streaming engine and the high level abstractions. + +The basic connectivity layer is a simple wrapper around the Confluent python +library, which is itself based on librdkafka. Besides some cosmetic changes, +this level provides a Fake in memory broker and consumer to make unit test quick +to run. + +The streaming engine provides an asynchronous processing interface to write +consumers. The consumer is written as a pipeline where each segment is an +asynchronous operation. The streaming engine implements the main consumer loop +and delegates the processing to the pipeline. + +On top of the streaming engine, the library provides high-level abstractions that +are common when writing Kafka consumers like: *map*, *reduce*, *filter* together +with some common messaging application patterns like the dead letter queue. + +Streaming Interface and Streaming Engine +---------------------------------------- + +A Kafka consumer is built as a pipeline where each segment processes messages in +an asynchronous way. The Streaming engine provides a message to a segment. The +segment is not supposed to execute small CPU work in a blocking way or do IO in a +non-blocking way. We generally use futures for this, and heavier CPU work in a +separate process. + +Arroyo provides an interface to implement to write a pipeline segment. +The segment interface is called *ProcessingStrategy* and is in +`this module `_. +(TODO: bring the docstrings to the docs and reference that). + +In most cases, when developing a consumer, the developer would not implement +that interface directly. A higher level abstraction would be used. + +.. figure:: _static/diagrams/arroyo_processing.png + +The main consumer loop is managed by the `stream engine `_. +These are the phases: + +* Poll from the Kafka consumer through the basic library. If a message is there + proceed or repeat. + +* Submit the message to the first *ProcessingStrategy*. This is supposed to deliver + work for the strategy to do. It is not supposed to be a blocking operation. The + strategy should return immediately. + +* Poll the strategy to execute work or to forward results to the following step + in the pipeline. Ideally all IO should be done in separate threads and heavy cpu + work should be done in separate processes so the *poll* method should check for + completed work, dispatch to the next step and return. In practice, work is executed + here in a blocking way if the overhead of offloading the work is too high. + +The *ProcessingStrategy* may decide not to take the message and instead apply back-pressure. +This is done by raising the *MessageRejected* exception. In this case, the streaming +engine pauses the consumer till the strategy is ready to accept the message. + +The *ProcessingStrategy* decides when it is time to commit a message. This is done +through a commit callback provided to the strategy when it is instantiated. + +The streaming engine orchestrates the life cycle of the *ProcessingStrategy*, thus +when it thinks it is time to shut the strategy down it would wait for all in-flight +work to be completed and then destroy the strategy. + +There are two scenarios where this can happen: + +* The consumer is being terminated. +* A rebalancing happened. A rebalancing revokes partitions and assigns new ones. + After a rebalancing is complete it is impossible to commit a message from a partition + that was revoked. In order to ensure the consumer behaves in a consistent way, + upon rebalancing, the streaming engine destroys the strategy and builds a new one. + This allows the strategy to complete all in-flight work before being terminated. + +High level strategies +----------------------- + +Most consumers follow the same few patterns, so Arroyo provides abstractions that +are based on the *ProcessingStrategy* but are simpler to implement for the common +use cases. + +Common examples are: + +* ``run task, run task in threads, run task with multiprocessing``. The run task + set of strategies are designed to be the most flexible and simple to use. They take + a function provided by the user and execute it on every message, passing the output + to the next step. The library includes synchronous and asynchronous versions depending + on the kind of concurrency required by the user. + +* ``filter, map and forward``. This type of consumer inspects a message, decides + whether to process it or discard it, transforms its content, and produces the result + on a new topic. In this case, Arroyo provides three implementations of the + *ProcessingStrategy*: *filter*, *transform*, and *produce*. The developer only needs + to wire them together and provide the map and filtering logic. + +* ``consume, apply side effects, produce``. This is a variation of the one above. + In this case, the transform operation can have side-effects like storing the content + of the message somewhere. + +* ``high throughput cpu intensive transform``. The python GIL does not allow CPU intensive + work to take advantage of parallelism. Arroyo provides an implementation of the *map* + pattern that batches messages and dispatches the work to separate processes via shared + memory. This is largely transparent to the developers. + +* ``map, reduce and store``. The reduce function is carried out by the *Collector*, which + batches messages and executes some logic with side-effects when the batch is full. + This is a typical way to write messages on a storages in batches to reduce the + round trips. + +All strategies included with Arroyo are in `the strategies module `_. diff --git a/_sources/backpressure.rst.txt b/_sources/backpressure.rst.txt new file mode 100644 index 00000000..2dcc20df --- /dev/null +++ b/_sources/backpressure.rst.txt @@ -0,0 +1,43 @@ +Backpressure +============ + +.. py:currentmodule:: arroyo.processing.strategies + +Arroyo's own processing strategies internally apply backpressure by raising +:py:class:`~abstract.MessageRejected`. Most +consumers do not require additional work to deal with backpressure correctly. + +If you want to slow down the consumer based on some external signal or +condition, you can achieve that most effectively by raising the same exception +from within a callback passed to :py:class:`~run_task.RunTask` while the +consumer is supposed to be paused + +.. code-block:: Python + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + def __init__(self): + self.is_paused = False + + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]: + if self.is_paused: + raise MessageRejected() + + print(f"MSG: {message.payload}") + return message + + return RunTask(handle_message, CommitOffsets(commit)) + +It is not recommended to apply backpressure by just ``sleep()``-ing in +:py:class:`~abstract.ProcessingStrategy.submit` (or, in this example, +``handle_message``) for more than a few milliseconds. While this definitely +pauses the consumer, it will block the main thread for too long and and prevent +things like consumer rebalancing from occuring. + +A 0.01 second sleep is applied each time :py:class:`~abstract.MessageRejected` is +raised to prevent the main thread spinning at 100% CPU. However background thread +performance may be impacted during this time. diff --git a/_sources/dlqs.rst.txt b/_sources/dlqs.rst.txt new file mode 100644 index 00000000..62562a39 --- /dev/null +++ b/_sources/dlqs.rst.txt @@ -0,0 +1,21 @@ +================== +Dead letter queues +================== + +.. warning:: + Dead letter queues should be used with caution as they break some of the ordering guarantees + otherwise offered by Arroyo and Kafka consumer code. In particular, it must be safe for the + consumer to drop a message. If replaying or later re-processing of the DLQ'ed messages is done, + it is critical that ordering is not a requirement in the relevant downstream code. + +Arroyo provides support for routing invalid messages to dead letter queues in consumers. +Dead letter queues are critical in some applications because messages are ordered in Kafka +and a single invalid message can cause a consumer to crash and every subsequent message to +not be processed. + +The dead letter queue configuration is passed to the `StreamProcessor` and, if provided, any +`InvalidMessage` raise by a strategy will be produced to the dead letter queue. + + +.. automodule:: arroyo.dlq + :members: InvalidMessage, DlqLimit, DlqPolicy, DlqProducer, KafkaDlqProducer, NoopDlqProducer diff --git a/_sources/getstarted.rst.txt b/_sources/getstarted.rst.txt new file mode 100644 index 00000000..1051739f --- /dev/null +++ b/_sources/getstarted.rst.txt @@ -0,0 +1,226 @@ +=========================== +Getting started with Arroyo +=========================== + +This tutorial shows how to create a Kafka consumer with Arroyo from scratch. + +Setup +===== + +This section explains how to setup Kafka, Zookeeper and install the library + +Kafka and Zookeeper +------------------- + +In order to run an arroyo Kafka consumer you will need a working Kafka broker. +If you already have one, you can skip this step. +If you do not have a running Kafka broker, this command will install and start +a Kafka docker container. (It requires Docker to be installed). + +.. code-block:: Bash + + docker network create arroyo + + docker run --rm \ + -v zookeeper_volume:/var/lib/zookeeper \ + --env ZOOKEEPER_CLIENT_PORT=2181 \ + --name=sentry_zookeeper \ + --network=arroyo \ + -p 2181:2181 \ + confluentinc/cp-zookeeper:6.2.0 + + docker run --rm \ + -v kafka_volume:/var/lib/kafka \ + --env KAFKA_ZOOKEEPER_CONNECT=sentry_zookeeper:2181 \ + --env KAFKA_LISTENERS=INTERNAL://0.0.0.0:9093,EXTERNAL://0.0.0.0:9092 \ + --env KAFKA_ADVERTISED_LISTENERS=INTERNAL://127.0.0.1:9093,EXTERNAL://127.0.0.1:9092 \ + --env KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT \ + --env KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL \ + --env KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \ + --env CONFLUENT_SUPPORT_METRICS_ENABLE=false \ + --env KAFKA_LOG4J_LOGGERS=kafka.cluster=WARN,kafka.controller=WARN,kafka.coordinator=WARN,kafka.log=WARN,kafka.server=WARN,kafka.zookeeper=WARN,state.change.logger=WARN \ + --env KAFKA_LOG4J_ROOT_LOGLEVEL=WARN \ + --env KAFKA_TOOLS_LOG4J_LOGLEVEL=WARN \ + --name=sentry_kafka \ + --network=arroyo \ + -p 9092:9092 \ + confluentinc/cp-kafka:6.2.0 + +Now you should see Kafka and Zookeeper running with + +.. code-block:: Bash + + docker ps + +Install Kafkacat +---------------- + +This tool will be useful to produce onto and consume from topics. + +.. code-block:: Bash + + https://docs.confluent.io/platform/current/app-development/kafkacat-usage.html#kcat-formerly-kafkacat-utility + + +Development environment +----------------------- + +You will need to install the library. Most likely in a python venv. So first, create a python virtual +environment. Then you can install arroyo with this. + +.. code-block:: Bash + + pip install sentry-arroyo + +Create two Kafka topics +----------------------- + +Our example will consume from one topic and produce the same messages on another topic. So we need +two topics. + +.. code-block:: Bash + + docker exec sentry_kafka kafka-topics \ + --create \ + --topic source-topic \ + --bootstrap-server 127.0.0.1:9092 + + docker exec sentry_kafka kafka-topics \ + --create \ + --topic dest-topic \ + --bootstrap-server 127.0.0.1:9092 + +Now you should be ready to develop with Arroyo. + +Create a basic consumer +======================= + +Arroyo provides two level of abstractions when writing a consumer: the basic consumer/producer library +and the Streaming library. The first is just a thin wrapper around a librdkafka consumer/producer that +adds some features around offset management. The second provides a more abstract streaming interface +that hides details like rebalancing and the consumer lifecycle. + +Creating a basic consumer +------------------------- + +This initializes a basic consumer and consumes a message. + +.. code-block:: Python + + from arroyo.backends.kafka.configuration import ( + build_kafka_consumer_configuration, + ) + from arroyo.backends.kafka.consumer import KafkaConsumer + from arroyo.types import Topic + + TOPIC = Topic("source-topic") + + consumer = KafkaConsumer( + build_kafka_consumer_configuration( + default_config={}, + bootstrap_servers=["127.0.0.1:9092"], + auto_offset_reset="latest", + group_id="test-group", + ) + ) + + consumer.subscribe([TOPIC]) + + while True: + msg = consumer.poll(timeout=1.0) + if msg is not None: + print(f"MSG: {msg.payload}") + +Start this script and use kcat to produce a message: + +.. code-block:: Bash + + echo "MESSAGE" | kcat -P -b 127.0.0.1:9092 -t source-topic + +In a while the message should appear on the console: + +.. code-block:: Bash + + MSG: KafkaPayload(key=None, value=b'MESSAGE', headers=[]) + + +Create a streaming consumer +--------------------------- + +Add a `ProcessingStrategy` and `ProcessingStrategyFactory`. +Here we are using the `RunTask` strategy which runs a custom function over each message. + +.. code-block:: Python + + def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]: + print(f"MSG: {message.payload}") + return message + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + """ + The factory manages the lifecycle of the `ProcessingStrategy`. + A strategy is created every time new partitions are assigned to the + consumer, while it is destroyed when partitions are revoked or the + consumer is closed + """ + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + return RunTask(handle_message, CommitOffsets(commit)) + +The code above is orchestrated by the Arroyo runtime called `StreamProcessor`. + +.. code-block:: Python + + processor = StreamProcessor( + consumer=consumer, + topic=TOPIC, + processor_factory=ConsumerStrategyFactory(), + ) + + processor.run() + +The main consumer loop is managed by the `StreamProcessor` no need to periodically poll the +consumer. The `ConsumerStrategy` works by inversion of control. + +Add some useful logic +--------------------- + +Now we will chain the `Produce` strategy to produce messages on a second topic after the message is logged + +.. code-block:: Python + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + """ + The factory manages the lifecycle of the `ProcessingStrategy`. + A strategy is created every time new partitions are assigned to the + consumer, while it is destroyed when partitions are revoked or the + consumer is closed + """ + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + producer = KafkaProducer( + build_kafka_configuration( + default_config={}, + bootstrap_servers=BOOTSTRAP_SERVERS, + ) + ) + + return RunTask( + handle_message, + Produce(producer, Topic("dest-topic"), CommitOffsets(commit)) + ) + +The message is first passed to the `RunTask` strategy which simply logs the message and submits +the output to the next step. The `Produce` strategy produces the message asynchronously. Once +the message is produced, the `CommitOffsets` strategy commits the offset of the message. + +Further examples +================ + +Find some complete `examples of usage `_. diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 00000000..fb702775 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,16 @@ +.. include:: intro.rst + +Contents: +--------- + +.. toctree:: + :maxdepth: 2 + + what_for + getstarted + architecture + strategies/index + offsets + dlqs + backpressure + metrics diff --git a/_sources/intro.rst.txt b/_sources/intro.rst.txt new file mode 100644 index 00000000..72b0d4e2 --- /dev/null +++ b/_sources/intro.rst.txt @@ -0,0 +1,15 @@ +.. image:: _static/arroyo-banner.png + :width: 583 + :height: 95 + +Arroyo is a library to build streaming applications that consume from +and produce to Kafka. + +It relies on the `confluent_kafka` python library, which itself relies +on `librdkafka`. + +Arroyo provides mainly three functionalities: + +* A set of abstractions inspired to common messaging applications patterns. +* Some abstractions to simplify offset management and rebalancing. +* An in memory broker abstraction to simplify writing unit tests. diff --git a/_sources/metrics.rst.txt b/_sources/metrics.rst.txt new file mode 100644 index 00000000..94011dbe --- /dev/null +++ b/_sources/metrics.rst.txt @@ -0,0 +1,53 @@ +================== +Metrics +================== + + +Arroyo consumers and strategies attempt to auto instrument some metrics that most people find useful +to understand the behavior and performance of their consumers. These metrics are typically sampled or +buffered as appropriate and flushed periodically (often once per second). + +In order to use these metrics, you must configure a metrics backend that conforms to the metrics protocol +before creating your consumer. + +This can be done like so: + +.. code:: python + + from arroyo.utils.metrics import Metrics, MetricName + + class MyMetrics(Metrics): + def increment( + self, name: MetricName, value: Union[int, float] = 1, tags: Optional[Tags] = None + ) -> None: + # Increment a counter by the given value. + record_incr(name, value, tags) + + def gauge( + self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None + ) -> None: + # Sets a gauge metric to the given value. + record_gauge(name, value, tags) + + def timing( + self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None + ) -> None: + # Emit a timing metric with the given value. + record_timing(name, value, tags) + + metrics_backend = MyMetrics() + + configure_metrics(metrics_backend) + + +Available Metrics +==================== + +.. literalinclude:: ../../arroyo/utils/metric_defs.py + +API +======= + +.. automodule:: arroyo.utils.metrics + :members: + :undoc-members: diff --git a/_sources/offsets.rst.txt b/_sources/offsets.rst.txt new file mode 100644 index 00000000..6316e653 --- /dev/null +++ b/_sources/offsets.rst.txt @@ -0,0 +1,37 @@ +================== +Committing offsets +================== + +Arroyo does not auto commit offsets. It is up to you to manually commit offsets when processing for that +message is completed. + +The commit callback will be passed to processing strategy via `ProcessingStrategyFactory.create_with_partitions`. +You should pass this to the strategy and have your strategy call this commit function once the rest of the message +processing has been done. + +The offset to be committed in Kafka is always the next offset to be consumed from, i.e. message's offset + 1. +In Arroyo, this means you should commit `Message.next_offset` and never `Message.offset` when done processing +that message. Arroyo exposes `Message.position_to_commit` to make this easier. + +It is not safe to commit every offset in a high throughput consumer as this will add a lot of load to the system. +Commits should generally be throttled. `CommitPolicy` is the Arroyo way of specifying commit frequency. A `CommitPolicy` +must be passed to the stream processor, which allows specifying a minimum commit frequency (or messages between commits). +Commit throttling can be skipped when needed (i.e. during consumer shutdown) by passing `force=True` to the commit callback. +If you are not sure how often to commit, `ONCE_PER_SECOND` is a reasonable option. + +The easiest way is to use the `CommitOffsets` strategy as the last step in a chain of processing strategies to commit offsets. + +.. code-block:: Python + + class MyConsumerFactoryFactory(ProcessingStrategyFactory[KafkaPayload]): + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + def my_processing_function(message: Message[KafkaPayload]) -> None: + # do something (synchronous) with the message + do_something() + + + return RunTask(my_processing_function, CommitOffsets(commit)) diff --git a/_sources/strategies/batching.rst.txt b/_sources/strategies/batching.rst.txt new file mode 100644 index 00000000..540d7d8a --- /dev/null +++ b/_sources/strategies/batching.rst.txt @@ -0,0 +1,10 @@ +Batch and Unbatch +----------------------------- + +Accumulate messages into a batch and pass to the next step. +The batch and unbatch strategies are based on reduce and unfold. +Use reduce/unfold instead if you want to provide custom +accumulator/generator functions. + +.. automodule:: arroyo.processing.strategies.batching + :members: diff --git a/_sources/strategies/commit_offsets.rst.txt b/_sources/strategies/commit_offsets.rst.txt new file mode 100644 index 00000000..64d3504c --- /dev/null +++ b/_sources/strategies/commit_offsets.rst.txt @@ -0,0 +1,8 @@ +Commit offsets +----------------------------- + +Should be used as the last strategy in the chain, to ensure +that offsets are only committed once all processing is complete. + +.. automodule:: arroyo.processing.strategies.commit + :members: diff --git a/_sources/strategies/filter.rst.txt b/_sources/strategies/filter.rst.txt new file mode 100644 index 00000000..22cba221 --- /dev/null +++ b/_sources/strategies/filter.rst.txt @@ -0,0 +1,5 @@ +Filter +----------------------------- + +.. automodule:: arroyo.processing.strategies.filter + :members: diff --git a/_sources/strategies/healthcheck.rst.txt b/_sources/strategies/healthcheck.rst.txt new file mode 100644 index 00000000..89fe7a3c --- /dev/null +++ b/_sources/strategies/healthcheck.rst.txt @@ -0,0 +1,74 @@ +Healthchecks +============ + +If your code blocks for too long in the main thread, the consumer can turn +unhealthy. + +Kafka has a setting called ``max.poll.interval.ms`` for this that tells Kafka +to kick the consumer out of the broker after this many milliseconds of not polling. + +You can pass this option into :py:class:`arroyo.backends.kafka.consumer.KafkaConsumer` like so: + +.. code-block:: Python + + consumer = KafkaConsumer( + { + "max.poll.interval.ms": 300000, # default 5 minutes + } + ) + +However, this will not shut down the consumer, it will just keep running doing +nothing (because it is blocked in the main thread). You want a pod-level +healthcheck as well. + +Arroyo supports touching a file repeatedly from the main thread to indicate +health. Start your pipeline with the +:py:class:`arroyo.processing.strategies.healthcheck.Healthcheck` strategy. + +.. code-block:: Python + + def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]: + ... + return message + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + def __init__(self): + self.is_paused = False + + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + step = RunTask(handle_message, CommitOffsets(commit)) + return Healthcheck("/tmp/health.txt", step) + +The Kubernetes `liveness +`_ +command would look like: + +.. code-block:: YAML + + apiVersion: v1 + kind: Pod + metadata: + labels: + test: liveness + name: liveness-exec + spec: + containers: + - name: liveness + image: registry.k8s.io/busybox + args: + - bin/my_arroyo_consumer + livenessProbe: + exec: + command: + - rm + - /tmp/health.txt + initialDelaySeconds: 5 + periodSeconds: 320 # should be higher than max.poll.interval.ms + + +.. automodule:: arroyo.processing.strategies.healthcheck + :members: diff --git a/_sources/strategies/index.rst.txt b/_sources/strategies/index.rst.txt new file mode 100644 index 00000000..1c373df0 --- /dev/null +++ b/_sources/strategies/index.rst.txt @@ -0,0 +1,38 @@ +Processing Strategies +===================== + +The processing strategies are the components to be wired together to +build a consumer. + +Strategy interface +------------------------- + +We normally don't recommend writing your own strategy, and encourage you to use +built-in ones such as "reduce" or "run task" to plug in your application logic. +Nevertheless, all arroyo strategies are written against the following interface: + +.. automodule:: arroyo.processing.strategies.abstract + :members: + :undoc-members: + :show-inheritance: + +Messages +------------ + +.. automodule:: arroyo.types + :members: + :undoc-members: + +.. toctree:: + :hidden: + + filter + reduce + unfold + batching + run_task + run_task_in_threads + run_task_with_multiprocessing + produce + commit_offsets + healthcheck diff --git a/_sources/strategies/produce.rst.txt b/_sources/strategies/produce.rst.txt new file mode 100644 index 00000000..d40c3ba8 --- /dev/null +++ b/_sources/strategies/produce.rst.txt @@ -0,0 +1,5 @@ +Produce +----------------------------- + +.. automodule:: arroyo.processing.strategies.produce + :members: diff --git a/_sources/strategies/reduce.rst.txt b/_sources/strategies/reduce.rst.txt new file mode 100644 index 00000000..41be2365 --- /dev/null +++ b/_sources/strategies/reduce.rst.txt @@ -0,0 +1,7 @@ +Reduce (Fold) +----------------------------- + +Accumulate messages based on a custom accumulator function + +.. automodule:: arroyo.processing.strategies.reduce + :members: diff --git a/_sources/strategies/run_task.rst.txt b/_sources/strategies/run_task.rst.txt new file mode 100644 index 00000000..bce67b48 --- /dev/null +++ b/_sources/strategies/run_task.rst.txt @@ -0,0 +1,5 @@ +Run Task +----------------------------- + +.. automodule:: arroyo.processing.strategies.run_task + :members: diff --git a/_sources/strategies/run_task_in_threads.rst.txt b/_sources/strategies/run_task_in_threads.rst.txt new file mode 100644 index 00000000..84ea0c08 --- /dev/null +++ b/_sources/strategies/run_task_in_threads.rst.txt @@ -0,0 +1,5 @@ +Run Task in Threads +----------------------------- + +.. automodule:: arroyo.processing.strategies.run_task_in_threads + :members: diff --git a/_sources/strategies/run_task_with_multiprocessing.rst.txt b/_sources/strategies/run_task_with_multiprocessing.rst.txt new file mode 100644 index 00000000..1855dbbd --- /dev/null +++ b/_sources/strategies/run_task_with_multiprocessing.rst.txt @@ -0,0 +1,5 @@ +Run Task with Multiprocessing +----------------------------- + +.. automodule:: arroyo.processing.strategies.run_task_with_multiprocessing + :members: diff --git a/_sources/strategies/unfold.rst.txt b/_sources/strategies/unfold.rst.txt new file mode 100644 index 00000000..113dc3b7 --- /dev/null +++ b/_sources/strategies/unfold.rst.txt @@ -0,0 +1,7 @@ +Unfold +----------------------------- + +Generates a sequence of messages from a single message based on a custom generator function + +.. automodule:: arroyo.processing.strategies.unfold + :members: diff --git a/_sources/what_for.rst.txt b/_sources/what_for.rst.txt new file mode 100644 index 00000000..7e2d04fd --- /dev/null +++ b/_sources/what_for.rst.txt @@ -0,0 +1,276 @@ +What is Arroyo for? +=================== + +Arroyo is a library for writing high-throughput, testable kafka +consumers and producers. This document attempts to outline the +intricacies of writing such consumers. + +Goals +----- + +1. Make it easy to build consumers that provide delivery guarantees +2. Make it easy to write high-throughput kafka consumers +3. Make it easy to write reliable, high throughput kafka producers +4. Abstract away rebalancing such that users of the library do not have + to worry about it +5. Make it possible to test kafka consumer logic without having to + reproduce the entire kafka environment +6. Provide a way for the application logic to signal backpressure + +Why Simple Doesn’t Cut It +------------------------- + +When visualizing event-driven architecture, Kafka is viewed as an +abstract queue with groups of producers pushing to it, and consumers +consuming from it (as in the diagram below). + +.. mermaid:: + + graph TD + Producer --> Kafka_Topic + Kafka_Topic --> Consumer + Consumer --> Destination + +A more accurate model is that kafka is like a log file which is +persistent and there are offsets of the file that different consumers +have read or not read. + +The most simple kafka consumer looks something like this: + +.. code:: python + + from confluent_kafka import Consumer + + conf = { + "bootstrap.servers": "localhost:9092", + "group.id": "my_group", + "auto.offset.reset": "latest", + } + + consumer = Consumer(conf) + consumer.subscribe(["my_topic"]) + + while True: + message = consumer.poll() + send_to_destination(process_message(message)) + +This simple consumer would not satisfy the goals mentioned at the top of +this page. The following subsections will explain why + +Providing delivery guarantees +----------------------------- + +By default, a consumer in the ``confluent_kafka`` library will +auto-commit on poll. To understand what it means to commit to a kafka +topic, see the Appendix. This can lead to the following issue: + +.. code:: python + + # get message from kafka, commit immediately + message = consumer.poll() + # ❗❗❗ throws exception due to a network issue + send_to_destination(process_message(message)) + # this message is now lost and we're on to the next one + +This can be fixed by only committing after we know that the message has +reached its destination in the following way: + +.. code:: python + + # add this value to the config: + "enable.auto.commit": "false" + # ------- + message = consumer.poll(timeout=0) + send_to_destination(process_message(message)) + consumer.commit(message.offset()) + +High Throughput +--------------- + +The previous section has allowed us to not commit messages that are not +processed however committing every message severely hurts throughput. +Every call to commit is a network operation, it also makes the broker +persist and replicate the information. If we can reduce the number of +commit calls, our throughput can be much higher. And so we commit in +batches + +.. code:: python + + # this code is purely descriptive. + # We have to commit to each partition separately + # but that code is not helpful for this example + message = consumer.poll(timeout=0) + batch.append(process_message(message)) + if len(batch) == batch_size: + consumer.commit(offsets=[m.offset() for m in batch]) + +This will get us faster throughput however we are currently hand-waving +away how we send the message to its destination + +Reliable High Throughput Batched Producers +------------------------------------------ + +Producing to Kafka reliably and at high throughput is not a simple +operation. Here is how a simple Kafka Producer looks in code: + +.. code:: python + + from confluent_kafka import Producer + + conf = { + "bootstrap.servers": "localhost:9092", + } + producer = Producer(conf) + def send_to_destination(message): + # ❗ This does not do what it says + # it writes to a buffer + producer.produce("destination_topic", message) + # this will actually block until the messages are produced + # calling this after produce every time is very expensive, + # how often we flush has high impacts on the producer throughput + producer.flush() + + +At a high level, the producer is actually buffering the messages +produced to the topic + +.. image:: _static/diagrams/kafka_producer.png + +A kafka producer writes to an internal buffer. This batches the IO +(good) but you don’t know when it will ever make it to the +destination + +In order to allow for reliability of transmission, the +``confluent_kafka`` library provides `a callback to +produce `__ +like so + +.. code:: python + + def delivery_callback(error, message): + # do something here to make sure your message is in the state + # you want it to be + + producer.produce("destination_topic", message, on_delivery=delivery_callback) + +Dealing With Rebalancing +------------------------ + +What is Rebalancing +~~~~~~~~~~~~~~~~~~~ + +A kafka topic is divided into n partitions, each partition can be +consumed by exactly one consumer per `consumer +group `__. A consumer can +consume multiple partitions + +.. figure:: _static/diagrams/consumer_groups.png + +When Rebalancing Can Happen +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rebalancing can happen due to: + +- An addition or removal of a consumer to a consumer group + + - (Every deploy does this) + +- A rebalance being kicked off manually +- A consumer pod dies and now its partition needs to be re-assigned +- Whenever the broker decides it’s a good idea (it can happen at any + time) +- TODO: More things? + +How Rebalancing Affects a Consumer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rebalancing is annoying to handle for a consumer that processes batches, +imagine the following scenario: + +.. mermaid:: + + sequenceDiagram + Broker->>Consumer: message + activate Consumer + note right of Consumer: start building batch + Broker->>Consumer: message + Broker->>Consumer: Revoke Partition + deactivate Consumer + Consumer->>Broker: commit batch + note left of Broker: Received commit from revoked Consumer! + +Once a partition is revoked for a consumer, it cannot commit to it. This +is bad news for the batch that the consumer has built up. Each consumer +has different requirements but a decision has to be made as to whether +to flush the batch or to discard its work and let the next consumer +assigned to this partition pick it up. The rebalancing behavior can be +customized by providing an ``on_revoke`` callback to the consumer when +subscribing. + +.. code:: python + + from confluent_kafka import Consumer + + conf = { + "bootstrap.servers": "localhost:9092", + "group.id": "my_group", + "auto.offset.reset": "latest", + } + + def flush_current_batch(consumer, partitions): + # flush the current batch + pass + + consumer = Consumer(conf) + consumer.subscribe(["my_topic"], on_revoke=flush_current_batch) + +librdkafka’s Callback Hell +-------------------------- + +librdkafka uses callbacks as a core mechanic for control flow. A few +such examples have been mentioned in this document already. What is not +clear however, is that **callbacks are only called when ``poll`` is +called** + +This means that: + +- this line could possibly do a lot of work: + +.. code:: python + + # any scheduled callbacks will run within this call + message = consumer.poll() + +- No callbacks will be invoked until the consumer or producer call + ``poll`` again (for their respective callbacks) +- ``poll`` has to be called periodically on a consumer otherwise the + broker will kick the consumer out of the consumer group + + - The handling of that revocation won’t happen until ``poll`` is + called + +Conclusion +---------- + +There are many intricacies and gotchas to writing high performant, +reliable kafka consumers. This document does not outline all of them but +all of what is outlined here should be kept in mind when designing any +kafka consumer library. + +Appendix +-------- + +Committing to a Kafka Topic +--------------------------- + +A consumer comitting to a topic signals to the broker that this message +has been processed. When ``poll`` is called next by that consumer, it +will return the next message. + +`API +Doc `__ + +What is a Kafka Consumer Group +------------------------------ + +https://www.educba.com/kafka-consumer-group/ diff --git a/_static/arroyo-banner.png b/_static/arroyo-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..90482cb669dcc531ab025eb4e1c7afe9282381b7 GIT binary patch literal 71723 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

#M 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

?H$}{j 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 o$bt4xlA4 literal 0 HcmV?d00001 diff --git a/_static/arroyo-logo.png b/_static/arroyo-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8c7952081ab4e8cb1704ba302e4c6b62d5744f73 GIT binary patch literal 13031 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 O0Qb~&)oN61qy8T(_&SyV literal 0 HcmV?d00001 diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..cfc60b86 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,921 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/custom.css b/_static/custom.css new file mode 100644 index 00000000..a738cff4 --- /dev/null +++ b/_static/custom.css @@ -0,0 +1,10 @@ +/* fix mermaid diagrams in dark mode of shibuya theme we use */ + +html.dark .mermaid path { + stroke: #fff !important; +} + +html.dark .mermaid .marker { + stroke: #fff !important; + fill: #fff !important; +} diff --git a/_static/diagrams/arroyo_processing.png b/_static/diagrams/arroyo_processing.png new file mode 100644 index 0000000000000000000000000000000000000000..21004ddec1f5b65e4d272411acb2bff5724232d2 GIT binary patch literal 19166 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 literal 0 HcmV?d00001 diff --git a/_static/diagrams/consumer_groups.png b/_static/diagrams/consumer_groups.png new file mode 100644 index 0000000000000000000000000000000000000000..09aa7440e8124155500b3f926c49c8331a2f22af GIT binary patch literal 23512 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 literal 0 HcmV?d00001 diff --git a/_static/diagrams/kafka_producer.png b/_static/diagrams/kafka_producer.png new file mode 100644 index 0000000000000000000000000000000000000000..53a90d9d95a203732b2380077dc2e9646a1f5db8 GIT binary patch literal 16532 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 JE0NIi`5%ZO4Bh|$ literal 0 HcmV?d00001 diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..d06a71d7 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..b57ae3b8 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 00000000..250f5665 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, is available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/_static/print.css b/_static/print.css new file mode 100644 index 00000000..e77b0820 --- /dev/null +++ b/_static/print.css @@ -0,0 +1,29 @@ +.sy-head-inner { + padding: 0; +} + +h1, h2, h3, h4, h5, h6 { + page-break-inside: avoid; + page-break-after: avoid; +} + +.code-block-caption, +pre, code { + page-break-inside: avoid; + white-space: pre-wrap; + + -webkit-print-color-adjust: exact; +} + +.admonition { + -webkit-print-color-adjust: exact; +} + +.sy-head { + position: static; + border-bottom: 1px solid var(--sy-c-divider); +} + +.highlight .linenos { + box-shadow: none; +} diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..a69833b6 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,63 @@ +.highlight { color: var(--syntax-text); background-color: transparent } +.highlight .hll { display: block; background-color: var(--syntax-highlight-bg) } +.highlight .c { color: var(--syntax-comment) } /* Comment */ +.highlight .err { color: var(--syntax-invalid-illegal-text); background-color: var(--syntax-invalid-illegal-bg) } /* Error */ +.highlight .g { color: var(--syntax-meta) } /* Generic */ +.highlight .k { color: var(--syntax-keyword) } /* Keyword */ +.highlight .l { color: var(--syntax-meta) } /* Literal */ +.highlight .o { color: var(--syntax-constant) } /* Operator */ +.highlight .x { color: var(--syntax-meta) } /* Other */ +.highlight .cm { color: var(--syntax-comment) } /* Comment.Multiline */ +.highlight .cp { color: var(--syntax-constant) } /* Comment.Preproc */ +.highlight .c1 { color: var(--syntax-comment) } /* Comment.Single */ +.highlight .cs { color: var(--syntax-comment); background-color: var(--syntax-special-bg) } /* Comment.Special */ +.highlight .gd { color: var(--syntax-markup-deleted-text); background-color: var(--syntax-markup-deleted-bg) } /* Generic.Deleted */ +.highlight .ge { color: var(--syntax-markup-italic); font-style: italic } /* Generic.Emph */ +.highlight .gr { color: var(--syntax-invalid-illegal-text); background-color: var(--syntax-invalid-illegal-bg) } /* Generic.Error */ +.highlight .gh { color: var(--syntax-markup-heading) } /* Generic.Heading */ +.highlight .gi { color: var(--syntax-markup-inserted-text); background-color: var(--syntax-markup-inserted-bg) } /* Generic.Inserted */ +.highlight .go { color: var(--syntax-meta) } /* Generic.Output */ +.highlight .gp { color: var(--syntax-meta) } /* Generic.Prompt */ +.highlight .gs { color: var(--syntax-markup-bold); font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: var(--syntax-markup-heading) } /* Generic.Subheading */ +.highlight .gt { color: var(--syntax-meta) } /* Generic.Traceback */ +.highlight .kc { color: var(--syntax-constant) } /* Keyword.Constant */ +.highlight .kd { color: var(--syntax-keyword) } /* Keyword.Declaration */ +.highlight .kn { color: var(--syntax-keyword) } /* Keyword.Namespace */ +.highlight .kp { color: var(--syntax-keyword) } /* Keyword.Pseudo */ +.highlight .kr { color: var(--syntax-keyword) } /* Keyword.Reserved */ +.highlight .kt { color: var(--syntax-entity) } /* Keyword.Type */ +.highlight .ld { color: var(--syntax-meta) } /* Literal.Date */ +.highlight .m { color: var(--syntax-constant) } /* Literal.Number */ +.highlight .s { color: var(--syntax-string) } /* Literal.String */ +.highlight .il { color: var(--syntax-constant) } /* Literal.Number.Integer.Long */ +.highlight .na { color: var(--syntax-constant) } /* Name.Attribute */ +.highlight .nb { color: var(--syntax-builtin) } /* Name.Builtin */ +.highlight .nc { color: var(--syntax-definition) } /* Name.Class */ +.highlight .no { color: var(--syntax-constant) } /* Name.Constant */ +.highlight .nd { color: var(--syntax-entity) } /* Name.Decorator */ +.highlight .ni { color: var(--syntax-entity) } /* Name.Entity */ +.highlight .ne { color: var(--syntax-exception) } /* Name.Exception */ +.highlight .nf { color: var(--syntax-definition) } /* Name.Function */ +.highlight .nt { color: var(--syntax-tag) } /* Name.Tag */ +.highlight .ow { color: var(--syntax-constant) } /* Operator.Word */ +.highlight .w { color: var(--syntax-meta) } /* Text.Whitespace */ +.highlight .mf { color: var(--syntax-constant) } /* Literal.Number.Float */ +.highlight .mh { color: var(--syntax-constant) } /* Literal.Number.Hex */ +.highlight .mi { color: var(--syntax-constant) } /* Literal.Number.Integer */ +.highlight .mo { color: var(--syntax-constant) } /* Literal.Number.Oct */ +.highlight .sb { color: var(--syntax-meta) } /* Literal.String.Backtick */ +.highlight .sc { color: var(--syntax-string) } /* Literal.String.Char */ +.highlight .sd { color: var(--syntax-comment) } /* Literal.String.Doc */ +.highlight .s2 { color: var(--syntax-string) } /* Literal.String.Double */ +.highlight .se { color: var(--syntax-string) } /* Literal.String.Escape */ +.highlight .sh { color: var(--syntax-comment) } /* Literal.String.Heredoc */ +.highlight .si { color: var(--syntax-string) } /* Literal.String.Interpol */ +.highlight .sx { color: var(--syntax-string) } /* Literal.String.Other */ +.highlight .sr { color: var(--syntax-regexp) } /* Literal.String.Regex */ +.highlight .s1 { color: var(--syntax-string) } /* Literal.String.Single */ +.highlight .ss { color: var(--syntax-string) } /* Literal.String.Symbol */ +.highlight .bp { color: var(--syntax-variable) } /* Name.Builtin.Pseudo */ +.highlight .vc { color: var(--syntax-variable) } /* Name.Variable.Class */ +.highlight .vg { color: var(--syntax-variable) } /* Name.Variable.Global */ +.highlight .vi { color: var(--syntax-variable) } /* Name.Variable.Instance */ diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 00000000..97d56a74 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,566 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = docUrlRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = docUrlRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/shibuya.css b/_static/shibuya.css new file mode 100644 index 00000000..a4db341e --- /dev/null +++ b/_static/shibuya.css @@ -0,0 +1 @@ +/*! tailwindcss v3.3.5 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.collapse{visibility:collapse}.order-last{order:9999}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.block{display:block}.flex{display:flex}.table{display:table}.contents{display:contents}.hidden{display:none}.w-64{width:16rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0}.max-w-6xl{max-width:72rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-x-1{--tw-translate-x:-0.25rem}.-translate-x-1,.-translate-x-2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-2{--tw-translate-x:-0.5rem}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.break-words{overflow-wrap:break-word}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pr-3{padding-right:.75rem}.pt-12{padding-top:3rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-sm{font-size:.875rem;line-height:1.25rem}@font-face{font-family:Twemoji Country Flags;unicode-range:u+1f1e6-1f1ff,u+1f3f4,u+e0062-e0063,u+e0065,u+e0067,u+e006c,u+e006e,u+e0073-e0074,u+e0077,u+e007f;src:url(https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1/dist/TwemojiCountryFlags.woff2) format("woff2")}html.light{color-scheme:light}html.dark{color-scheme:dark}::-moz-selection{color:rgba(var(--sy-rc-theme),1);background-color:rgba(var(--sy-rc-theme),.2)}::selection{color:rgba(var(--sy-rc-theme),1);background-color:rgba(var(--sy-rc-theme),.2)}body{font-family:var(--sy-f-text);color:var(--sy-c-text)}.win{font-family:"Twemoji Country Flags",var(--sy-f-text)}h1,h2,h3,h4,h5{color:var(--sy-c-heading);font-family:var(--sy-f-heading)}em,strong{color:var(--sy-c-bold)}.sy-container{max-width:90rem}.sy-scrollbar{overflow-y:auto;scrollbar-gutter:stable}.sy-scrollbar::-webkit-scrollbar{height:.75rem;width:.75rem}.sy-scrollbar::-webkit-scrollbar-thumb{border-radius:10px}.sy-scrollbar::-webkit-scrollbar-track{background-color:initial}.sy-scrollbar:hover::-webkit-scrollbar-thumb{background-color:#9b9b9b33;background-clip:content-box;border:3px solid #0000}.i-icon{-webkit-mask:var(--icon-url) no-repeat;mask:var(--icon-url) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;width:1em;height:1em;display:inline-block;vertical-align:middle;font-style:normal;background-color:currentColor}.theme-switch .theme-icon{--icon-url:var(--i-sun-url)}html.dark .theme-switch .theme-icon{--icon-url:var(--i-moon-url)}html.dark .dark-hidden,html.light .light-hidden{display:none}:root{--i-alert-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3zM12 9v4m0 4h.01'/%3E%3C/svg%3E");--i-arrows-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 15 5 5 5-5M7 9l5-5 5 5'/%3E%3C/svg%3E");--i-award-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='6'/%3E%3Cpath d='M15.477 12.89 17 22l-5-3-5 3 1.523-9.11'/%3E%3C/svg%3E");--i-bell-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9m-4.27 13a2 2 0 0 1-3.46 0'/%3E%3C/svg%3E");--i-bitbucket-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M.778 1.213a.768.768 0 0 0-.768.892l3.263 19.81c.084.5.515.868 1.022.873H19.95a.772.772 0 0 0 .77-.646l3.27-20.03a.768.768 0 0 0-.768-.891zM14.52 15.53H9.522L8.17 8.466h7.561z'/%3E%3C/svg%3E");--i-bookmark-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z'/%3E%3C/svg%3E");--i-calendar-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E");--i-check-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--i-chevron-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");--i-close-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--i-discord-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z'/%3E%3C/svg%3E");--i-external-link-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M13 5h6v6M19 5 5 19'/%3E%3C/svg%3E");--i-flame-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E");--i-git-fork-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='18' r='3'/%3E%3Ccircle cx='6' cy='6' r='3'/%3E%3Ccircle cx='18' cy='6' r='3'/%3E%3Cpath d='M18 9v1a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V9M12 12v3'/%3E%3C/svg%3E");--i-github-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E");--i-gitlab-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.875.875 0 0 0-1 .054.875.875 0 0 0-.29.44L16.47 7.818H7.537L5.332 1.07a.857.857 0 0 0-.29-.441.875.875 0 0 0-1-.054.859.859 0 0 0-.336.405L.433 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.03.021 4.977 3.727 2.462 1.863 1.5 1.132a1.008 1.008 0 0 0 1.22 0l1.499-1.132 2.461-1.863 5.006-3.75.013-.01a6.068 6.068 0 0 0 2.01-7.002z'/%3E%3C/svg%3E");--i-help-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3m.08 4h.01'/%3E%3C/svg%3E");--i-languages-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='lucide lucide-languages'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E");--i-laptop-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='12' rx='2' ry='2'/%3E%3Cpath d='M2 20h20'/%3E%3C/svg%3E");--i-link-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71'/%3E%3Cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71'/%3E%3C/svg%3E");--i-mastodon-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E");--i-menu-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='lucide lucide-menu'%3E%3Cpath d='M4 12h16M4 6h16M4 18h16'/%3E%3C/svg%3E");--i-milestone-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6H5a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h13l4-3.5L18 6zM12 13v8M12 3v3'/%3E%3C/svg%3E");--i-moon-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3a6.364 6.364 0 0 0 9 9 9 9 0 1 1-9-9z'/%3E%3C/svg%3E");--i-outdent-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 8-4 4 4 4M21 12H11M21 6H11M21 18H11'/%3E%3C/svg%3E");--i-rocket-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09zM12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z'/%3E%3Cpath d='M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5'/%3E%3C/svg%3E");--i-skull-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='12' r='1'/%3E%3Ccircle cx='15' cy='12' r='1'/%3E%3Cpath d='M8 20v2h8v-2m-3.5-3-.5-1-.5 1h1z'/%3E%3Cpath d='M16 20a2 2 0 0 0 1.56-3.25 8 8 0 1 0-11.12 0A2 2 0 0 0 8 20'/%3E%3C/svg%3E");--i-star-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E");--i-sun-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E");--i-x-twitter-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E");--i-youtube-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'/%3E%3C/svg%3E");--i-zap-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13 2 3 14h9l-1 8 10-12h-9l1-8z'/%3E%3C/svg%3E")}.i-icon.alert{--icon-url:var(--i-alert-url)}.i-icon.arrows{--icon-url:var(--i-arrows-url)}.i-icon.award{--icon-url:var(--i-award-url)}.i-icon.bell{--icon-url:var(--i-bell-url)}.i-icon.bitbucket{--icon-url:var(--i-bitbucket-url)}.i-icon.bookmark{--icon-url:var(--i-bookmark-url)}.i-icon.calendar{--icon-url:var(--i-calendar-url)}.i-icon.check{--icon-url:var(--i-check-url)}.i-icon.chevron{--icon-url:var(--i-chevron-url)}.i-icon.close{--icon-url:var(--i-close-url)}.i-icon.discord{--icon-url:var(--i-discord-url)}.i-icon.external-link{--icon-url:var(--i-external-link-url)}.i-icon.flame{--icon-url:var(--i-flame-url)}.i-icon.git-fork{--icon-url:var(--i-git-fork-url)}.i-icon.github{--icon-url:var(--i-github-url)}.i-icon.gitlab{--icon-url:var(--i-gitlab-url)}.i-icon.help{--icon-url:var(--i-help-url)}.i-icon.languages{--icon-url:var(--i-languages-url)}.i-icon.laptop{--icon-url:var(--i-laptop-url)}.i-icon.link{--icon-url:var(--i-link-url)}.i-icon.mastodon{--icon-url:var(--i-mastodon-url)}.i-icon.menu{--icon-url:var(--i-menu-url)}.i-icon.milestone{--icon-url:var(--i-milestone-url)}.i-icon.moon{--icon-url:var(--i-moon-url)}.i-icon.outdent{--icon-url:var(--i-outdent-url)}.i-icon.rocket{--icon-url:var(--i-rocket-url)}.i-icon.skull{--icon-url:var(--i-skull-url)}.i-icon.star{--icon-url:var(--i-star-url)}.i-icon.sun{--icon-url:var(--i-sun-url)}.i-icon.x-twitter{--icon-url:var(--i-x-twitter-url)}.i-icon.youtube{--icon-url:var(--i-youtube-url)}.i-icon.zap{--icon-url:var(--i-zap-url)}.hamburger{position:relative;display:inline-block;width:16px;height:14px;overflow:hidden;cursor:pointer}.hamburger>span{position:absolute;width:16px;height:2px;left:0;background-color:var(--sy-c-text);transition:top .25s,transform .25s}.hamburger_1{top:0}.hamburger_2{top:6px}.hamburger_3{top:12px}button[aria-expanded=true] .hamburger .hamburger_1{top:6px;transform:translate(0) rotate(225deg)}button[aria-expanded=true] .hamburger .hamburger_2{top:6px;transform:translate(18px)}button[aria-expanded=true] .hamburger .hamburger_3{top:6px;transform:translate(0) rotate(135deg)}.searchbox{position:relative}.searchbox input{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;padding:6px 12px;font-size:.92rem;font-family:var(--sy-f-text);border-radius:6px;outline:0;background:var(--sy-c-bg-weak)}.searchbox button,.searchbox kbd{position:absolute;font-size:.68rem;font-weight:600;font-family:var(--sy-f-mono);padding:2px 6px;margin:6px;right:0;border-radius:3px;border:1px solid var(--sy-c-border);background-color:var(--sy-c-bg);opacity:1;transition:opacity .2s ease}.searchbox input:focus+kbd{opacity:0}.searchform{display:flex;position:relative;align-items:center}.searchform input[name=q]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;padding:6px 12px;font-size:.92rem;font-family:var(--sy-f-text);border-radius:6px;outline:0;background:var(--sy-c-bg-weak)}.searchform input[name=q]+button{position:absolute;font-size:.68rem;font-weight:600;font-family:var(--sy-f-text);padding:2px 6px;margin:6px;right:0;border-radius:3px;border:1px solid var(--sy-c-divider);background-color:var(--sy-c-bg);opacity:1;transition:opacity .2s ease}.search .highlighted{background-color:var(--syntax-highlight-bg)}.demo{border:1px solid var(--sy-c-border);border-radius:6px}.demo-code .highlight>pre{border-bottom-left-radius:0;border-bottom-right-radius:0}.demo-result{padding:1rem}#ethical-ad-placement .ethical-sidebar{position:relative;background-color:var(--sy-c-bg-weak);border:none;padding:.8rem}#ethical-ad-placement .ethical-text a{color:var(--sy-c-text)!important}.sy-main #ethical-ad-placement .ethical-sidebar{margin-left:0;max-width:380px}.sy-main #ethical-ad-placement .ethical-image-link{flex-shrink:0;margin-right:.4rem}.sy-main #ethical-ad-placement .ethical-content{display:flex}.sy-main #ethical-ad-placement .ethical-text{margin-top:0}.sy-main #ethical-ad-placement .ethical-callout{position:absolute;right:.4rem;bottom:.4rem}#carbonads{margin:1rem 0;position:relative;display:block;background-color:var(--sy-c-bg-weak);border:none;border-radius:8px;padding:.8rem .8rem 1.6rem}#carbonads a{border:0;font-weight:400}#carbonads img{margin:0}.carbon-wrap{display:flex;align-items:center;justify-content:space-between;flex-direction:column}.carbon-text{display:block;margin:.5rem 0;line-height:1.42;font-size:.78rem;text-align:center}.carbon-text:hover{color:var(--sy-c-link)}.carbon-poweredby{position:absolute;right:.8rem;bottom:.5rem;font-size:.68rem;text-transform:uppercase}.carbon-poweredby:hover{text-decoration:underline}.sy-main #carbonads{max-width:380px;padding:1rem;margin-top:1.6rem}.sy-main .carbon-wrap{flex-direction:row;align-items:flex-start}.sy-main .carbon-text{text-align:left;margin-top:0;margin-left:1rem;font-size:.86rem}.bsa-bar{justify-content:space-between;padding:15px 20px;border-radius:10px;box-shadow:inset 0 0 2px #00000026;text-decoration:none}.bsa-bar,.bsa-main{display:flex;flex-flow:row nowrap;align-items:center}.bsa-main{flex-grow:1;justify-content:center;margin:0 auto}.bsa-img{max-height:40px;margin-right:20px;line-height:0}.bsa-details{display:flex;flex-flow:column nowrap;margin-right:20px}.bsa-tagline{margin-bottom:3px;font-weight:600;font-size:9px;line-height:1;letter-spacing:1.5px;text-transform:uppercase}.bsa-desc{max-width:600px;font-weight:400;font-size:12px;line-height:1.4;letter-spacing:1px}.bsa-cta{padding:10px 16px;transform:translateY(-1px);border-radius:3px;font-weight:600;font-size:10px;line-height:1;letter-spacing:1px;text-transform:uppercase;white-space:nowrap;transition:all .3s ease-in-out}@media (max-width:940px){.bsa-details{font-size:14px;margin-right:0}.bsa-cta{display:none}}@media (min-width:768px) and (max-width:820px){.bsa-img{display:none}}@media (max-width:480px){.bsa-img{display:none}}.repo-stats{margin-bottom:1rem;padding:.5rem 0;border-top:1px solid var(--sy-c-divider);border-bottom:1px solid var(--sy-c-divider)}.repo-stats-count{color:var(--sy-c-text-weak)}.repo-stats:hover .repo-stats-count{color:var(--sy-c-text)}.repo-stats strong{font-weight:500;font-family:var(--sy-f-mono);color:inherit}.edit-this-page{border-top:1px solid var(--sy-c-divider);margin:1rem 0;padding:.5rem 0;font-size:.8rem;font-weight:600}.repo-stats+.edit-this-page{border-top:0;margin-top:0;padding-top:0}.edit-this-page a{color:var(--sy-c-text-weak)}.edit-this-page a:hover{color:var(--sy-c-text)}.edit-this-page a:after{content:" →"}.announcement{position:sticky;top:0;left:0;width:100%;padding:.8rem 2rem;display:flex;align-items:center;color:var(--sy-c-banner,#fff);background-color:var(--sy-c-banner-bg,rgba(var(--sy-rc-theme),1));z-index:20}.announcement a{text-decoration:underline}.announcement ::-moz-selection{color:var(--sy-c-banner,#fff)}.announcement ::selection{color:var(--sy-c-banner,#fff)}.announcement-inner{width:100%;text-align:center}.announcement-close{position:absolute;top:.8rem;right:1rem}.sy-head{position:sticky;top:var(--sy-s-banner-height);height:var(--sy-s-navbar-height);background-color:initial;z-index:20}.sy-head-blur{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background-color:rgba(var(--sy-rc-bg),.85);z-index:-1;--tw-shadow:0 2px 4px rgba(var(--sy-rc-invert),.02),0 1px 0 rgba(var(--sy-rc-invert),.06);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.sy-head-inner{display:flex;padding-left:max(env(safe-area-inset-right),1.5rem);padding-right:max(env(safe-area-inset-right),1rem);justify-content:space-between;align-items:center;height:var(--sy-s-navbar-height)}.sy-head .i-icon{font-size:1.25rem}.sy-head-brand img{height:28px}.sy-head-brand .dark-logo,.sy-head-brand img+strong{display:none}.dark .sy-head-brand .dark-logo{display:inline}.dark .sy-head-brand .light-logo{display:none}.light .sy-head-brand .light-logo{display:inline}.light .sy-head-brand .dark-logo{display:none}.sy-head-nav a,.sy-head-nav button{padding:.5rem;font-size:.95rem;font-weight:500;white-space:nowrap}.sy-head-nav .link i.external-link{font-size:68%;opacity:.6;color:var(--sy-c-text-weak);margin-left:2px}.sy-head-nav .link>ul a{display:block}.sy-head-nav .link>ul a:hover{background:var(--sy-c-bg-weak);border-radius:6px}.sy-head-nav .link>ul small{display:block;color:var(--sy-c-text-weak);font-weight:400}.sy-head-social a{padding:.5rem}.sy-head-actions button{height:var(--sy-s-navbar-height);padding:0 .5rem}@media (max-width:767px){body[data-expanded-navlinks=true]{overflow:hidden}.sy-head-links{display:none;position:fixed;top:var(--sy-s-offset-top);bottom:0;left:0;right:0;padding:4rem 1.8rem 0;width:100%;box-sizing:border-box;border-top:1px solid var(--sy-c-divider);background-color:var(--sy-c-bg);overflow-y:auto}.sy-head-links._expanded{display:block}.sy-head-nav{margin-left:auto;margin-right:auto}.sy-head-nav .link{margin:.5rem 0}.sy-head-nav .link i.chevron{display:none}.sy-head-nav .link>ul{margin:.5rem 0 .5rem 1rem}.sy-head-extra form.searchbox{position:absolute;top:1rem;left:1.8rem;right:1.8rem}.sy-head-extra{flex-direction:column;padding:2rem 0 1rem;width:100%}}@media (min-width:768px){.sy-head-inner{padding-right:max(env(safe-area-inset-right),1.5rem)}.sy-head-links{display:flex;flex-grow:1;align-items:center;justify-content:space-between}.sy-head-nav{white-space:nowrap;overflow:auto}.sy-head-nav .link{display:inline-flex;align-items:center;height:var(--sy-s-navbar-height)}.sy-head-nav a:hover{color:rgba(var(--sy-rc-invert),1)}.sy-head-nav .link:hover>a{background-color:var(--sy-c-bg-weak);border-radius:6px}.sy-head-nav .link i.chevron{opacity:.6;font-size:1rem;transform:rotate(90deg)}.sy-head-nav .link>ul{position:absolute;height:0;visibility:hidden;background-color:var(--sy-c-bg);top:var(--sy-s-offset-top);margin-top:-10px;padding:15px;border-radius:6px;border:1px solid var(--sy-c-divider);box-shadow:0 12px 32px rgba(var(--sy-rc-invert),.1),0 2px 6px rgba(var(--sy-rc-invert),.08);z-index:9}.sy-head-nav .link:hover>ul{height:auto;visibility:visible}.sy-head-nav .link>ul>li{padding:.2rem 0}.sy-head-social{margin-left:.5rem}.sy-head-social a{padding:.5rem}}.sy-foot{border-top:1px solid var(--sy-c-foot-divider);padding-top:1.5rem;padding-bottom:1rem;color:var(--sy-c-foot-text);background-color:var(--sy-c-foot-bg)}.sy-foot-inner{padding-left:max(env(safe-area-inset-right),1.5rem);padding-right:max(env(safe-area-inset-right),1.5rem)}.sy-foot-copyright{font-size:.84rem}.sy-foot-copyright a{font-weight:500}.sy-foot-socials a{font-size:1.4rem;color:var(--sy-c-foot-text)}.sy-foot-socials a+a{margin-left:.5rem}.sy-lside li{margin:.6rem 0}.sy-lside li.link>span{font-size:.86rem;font-weight:500;font-family:var(--sy-f-heading);color:var(--sy-c-text-weak);text-transform:uppercase;letter-spacing:.4px}.sy-lside li.link .i-icon{display:none}.sy-lside li.link>ul{margin-left:1rem}.sy-lside li.link>ul small{display:none}.sy-lside .sidebar-links{margin-bottom:2rem}.sy-lside .sidebar-links span{display:inline-block;vertical-align:middle}.sy-lside .sidebar-links .icon{padding:.1rem;border-radius:6px;border:1px solid var(--sy-c-border);margin-right:.4rem;opacity:.8}.sy-lside .sidebar-links svg{width:1.5rem;height:1.5rem}.sy-lside .sidebar-links a:hover .icon{opacity:1}@media (min-width:768px){.sy-lside .sy-lside-inner{top:var(--sy-s-offset-top)}.sy-lside .sy-scrollbar{height:calc(100vh - var(--sy-s-offset-top));overflow-x:hidden}}.yue *{scroll-margin-top:calc(var(--sy-s-offset-top) + 68px)}.sy-content{max-width:64rem;min-height:calc(100vh - var(--sy-s-offset-top) - 80px)}@media (max-width:767px){#lside{position:fixed;z-index:18;top:var(--sy-s-offset-top);left:0;bottom:0;width:300px;max-width:100%;height:calc(100vh - var(---sy-s-offset-top));overflow:auto;background:rgba(var(--sy-rc-bg),.98);transform:translateX(-100%);transition:transform .2s ease}#lside._expanded{transform:translateX(0)}.lside-overlay{position:fixed;top:var(--sy-s-offset-top);left:0;width:0;height:0;background-color:rgba(var(--sy-rc-invert),.24);opacity:0;transition:width 0 .25s,height 0 .25s,opacity .25s}#lside._expanded+.lside-overlay{width:100%;height:100%;opacity:1;z-index:16}}@media (max-width:1279px){.sy-rside{position:fixed;z-index:25;top:0;right:0;bottom:0;width:20rem;max-width:100%;padding-top:2rem;padding-bottom:1rem;overflow:auto;background:var(--sy-c-bg);transform:translateX(110%);transition:transform .2s ease;--tw-shadow:-12px 0 16px rgba(var(--sy-rc-bg),0.16);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#rside._expanded{transform:translateX(0)}.rside-close{position:absolute;top:16px;right:16px;width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;font-size:1.4rem}.rside-overlay{position:fixed;top:0;left:0;width:0;height:0;background-color:rgba(var(--sy-rc-invert),.24);opacity:0;transition:width 0 .25s,height 0 .25s,opacity .25s}#rside._expanded+.rside-overlay{width:100%;height:100%;opacity:1;z-index:22}}@media (min-width:768px){.sy-main{width:calc(100% - 18rem);max-width:52rem}}@media (min-width:1280px){.sy-main{width:calc(100% - 34rem);max-width:none}.sy-rside .sy-scrollbar{max-height:calc(100vh - var(--sy-s-offset-top) - env(safe-area-inset-bottom))}.yue *{scroll-margin-top:calc(var(--sy-s-offset-top) + 24px)}}.nav-languages button,.nav-versions button{cursor:pointer;padding:0;margin:0;background:#0000;border:0;white-space:nowrap}.nav-versions .chevron{font-size:.72rem;font-weight:400;transform:rotate(90deg);color:var(--sy-c-text-weak)}@media (max-width:767px){.nav-languages,.nav-versions{width:100%;background-color:var(--sy-c-bg-weak);border-radius:6px;padding-bottom:.6rem;margin-bottom:1rem}.nav-languages button,.nav-versions button{padding:.5rem 1rem;font-weight:500;font-size:.76rem;color:var(--sy-c-text-weak)}.nav-languages button .i-icon,.nav-versions button .i-icon{display:none}.nav-versions ul{padding:0 .6rem}.nav-versions li{padding:.2rem .4rem;display:inline-block}.nav-languages li{font-size:.94rem;padding:.32rem 1rem}}@media (min-width:768px){.nav-languages,.nav-versions{display:flex;align-items:center;position:relative;width:auto;height:var(--sy-s-navbar-height);background:#0000;color:var(--sy-c-text)}.nav-languages button,.nav-versions button{padding:0 .5rem;border-right:1px solid var(--sy-c-divider-weak)}.nav-languages-choices,.nav-versions-choices{position:absolute;visibility:hidden;top:3rem;right:-.6rem;min-width:120px;box-sizing:border-box;background-color:var(--sy-c-bg);border-radius:6px;overflow:hidden;padding:.8rem 1rem;box-shadow:0 12px 32px rgba(var(--sy-rc-invert),.1),0 2px 6px rgba(var(--sy-rc-invert),.08)}.nav-languages:hover .nav-languages-choices,.nav-versions:hover .nav-versions-choices{visibility:visible}.nav-languages li,.nav-versions li{padding:.1rem 0}.nav-languages a,.nav-versions a{display:block;padding:.2rem .6rem;color:var(--sy-c-text);white-space:nowrap}.nav-languages a:hover,.nav-versions a:hover{color:var(--sy-c-link);background:var(--sy-c-bg-weak);border-radius:6px}}.sy-breadcrumbs{position:sticky;top:var(--sy-s-offset-top);background-color:var(--sy-c-bg);padding:0 1.5rem;z-index:5}.sy-breadcrumbs-inner{padding:.8rem 0;border-bottom:1px solid var(--sy-c-divider)}.sy-breadcrumbs ul{display:flex;font-size:.94rem;white-space:nowrap;overflow:auto}.sy-breadcrumbs button{display:flex;align-items:center}.sy-breadcrumbs ul a{color:var(--sy-c-text-weak)}.sy-breadcrumbs ul a:hover{color:var(--sy-c-bold)}.sy-breadcrumbs ul a+span{padding:0 .4rem;font-weight:300;color:var(--sy-c-text-weak)}@media (min-width:1280px){.sy-breadcrumbs{display:none}}@media (min-width:768px){.sy-breadcrumbs-inner{padding:1.5rem 0 1rem}}.globaltoc{padding-bottom:20px}.globaltoc .caption{font-size:.86rem;font-weight:500;font-family:var(--sy-f-heading);color:var(--sy-c-text-weak);text-transform:uppercase;letter-spacing:.4px;padding:.8rem 0 .4rem;border-top:1px solid var(--sy-c-divider)}.globaltoc>p.caption:first-of-type{padding-top:0;border-top:none}.globaltoc .caption+ul{margin-bottom:1.5rem}.globaltoc ul+.caption{margin-top:3rem}.globaltoc li{margin:.6rem 0}.globaltoc li>ul{margin-left:.6rem;font-size:.96rem}.globaltoc li.toctree-l1>ul{margin-left:.2rem;border-left:1px solid var(--sy-c-divider-weak)}.globaltoc li.toctree-l2{padding-left:.9rem;margin-left:-1px;border-left:1px solid #0000}.globaltoc li.toctree-l2.current{border-color:var(--sy-c-link)}.globaltoc>ul a.current{font-weight:500;color:var(--sy-c-link)}.globaltoc>ul a:hover{color:var(--sy-c-link-weak)}.globaltoc li{position:relative}.globaltoc li>button{position:absolute;top:.2rem;right:0;display:flex;justify-content:center;align-items:center;width:1.2rem;height:1.2rem;border-radius:3px}.globaltoc li>button:hover{background-color:var(--sy-c-bg-weak)}.globaltoc li._expand>ul,.globaltoc li.current>ul{display:block}.globaltoc li._collapse>ul,.globaltoc li>ul{display:none}.globaltoc li>button .chevron{transform:rotate(0deg);transition:transform .2s ease}.globaltoc li._expand>button .chevron,.globaltoc li.current>button .chevron{transform:rotate(90deg)}.globaltoc li._collapse>button .chevron{transform:rotate(0deg)}.sy-deprecated{padding:.8rem;font-size:.85rem;background-color:#ffdd001a;border-radius:6px}.sy-deprecated a{color:var(--sy-c-link);text-decoration:underline}.sy-deprecated a:hover{color:var(--sy-c-link-weak)}.sy-rside-inner>div{margin-bottom:1rem}.sy-rside-inner>div>h3{font-size:.8rem;font-weight:500;letter-spacing:.4px;text-transform:uppercase;margin-bottom:1rem}html[lang=ja] .sy-rside-inner>div>h3,html[lang=ko] .sy-rside-inner>div>h3,html[lang=zh-TW] .sy-rside-inner>div>h3,html[lang=zh] .sy-rside-inner>div>h3{letter-spacing:0;font-size:.86rem;font-weight:600}.localtoc>ul li{margin-top:.36rem;margin-bottom:.36rem}.localtoc>ul li>a:hover{color:var(--sy-c-link-weak)}.localtoc>ul li.active>a{font-weight:500;color:var(--sy-c-link)}.localtoc>ul>li ul{padding-left:.8rem}.sy-rside ul.this-page-menu{margin-top:-.6rem}.sy-rside ul.this-page-menu a{font-size:.96rem}.sy-rside ul.this-page-menu a:hover{color:var(--sy-c-link-weak)}.navigation{gap:2rem;margin-top:2rem;padding-top:1rem;border-top:1px solid var(--sy-c-divider)}.navigation>div{width:100%}.navigation a{display:inline-flex;align-items:center}.navigation a:hover{color:rgba(var(--sy-rc-invert),1)}.navigation-prev i.chevron{transform:rotate(180deg)}.navigation-next{text-align:right}.navigation-next a{justify-content:end}.navigation .page-info{padding:0 8px}.navigation .page-info>span{font-size:.8rem;color:var(--sy-c-text-weak)}.yue{--yue-c-black:#111827;--yue-c-text:var(--sy-c-text);--yue-c-heading:var(--sy-c-heading);--yue-c-bold:var(--sy-c-bold);--yue-c-link-1:var(--sy-c-text);--yue-c-link-2:var(--yue-c-black);--yue-c-link-border-1:rgba(var(--sy-rc-theme),0.8);--yue-c-link-border-2:rgb(var(--sy-rc-theme));--yue-c-ol-marker:#6b7280;--yue-c-ul-marker:#d1d5db;--yue-c-hr:#e5e7eb;--yue-c-quote:var(--yue-c-black);--yue-c-quote-border:#cfd3db;--yue-c-quote-symbol:rgba(var(--sy-rc-theme),1);--yue-c-caption:#6b7280;--yue-c-code:var(--yue-c-black);--yue-c-code-bg:#fff4d4;--yue-c-th-bg:#eff3f8;--yue-c-th-border:#d1d5db;--yue-c-td-border:#e5e7eb}html.dark .yue{--yue-c-link-1:var(--sy-c-text);--yue-c-link-2:#fff;--yue-c-ol-marker:#9ca3af;--yue-c-ul-marker:#4b5563;--yue-c-hr:#374151;--yue-c-quote:#f3f4f6;--yue-c-quote-border:#374151;--yue-c-caption:#9ca3af;--yue-c-code:#fff;--yue-c-code-bg:#312f29;--yue-c-th-bg:#24282e;--yue-c-th-border:#4b5563;--yue-c-td-border:#374151}.yue{font-size:1rem;line-height:1.75;color:var(--yue-c-text)}.yue p{margin-top:1rem;margin-bottom:1.25rem}.yue a{color:var(--yue-c-link-1);font-weight:500;text-decoration:none;border-bottom:1px solid var(--yue-c-link-border-1)}.yue a:hover{color:var(--yue-c-link-2);border-bottom:2px solid var(--yue-c-link-border-2)}.yue strong{color:var(--yue-c-bold);font-weight:600}.yue a strong,.yue blockquote strong,.yue thead th strong{color:inherit}.yue ol{margin-top:1.25em;margin-bottom:1.25em;padding-left:1.625em}.yue ol,.yue ol[type="1"]{list-style-type:decimal}.yue ol.upperalpha,.yue ol[type=A]{list-style-type:upper-alpha}.yue ol.loweralpha,.yue ol[type=a]{list-style-type:lower-alpha}.yue ol.upperroman,.yue ol[type=I]{list-style-type:upper-roman}.yue ol.lowerroman,.yue ol[type=i]{list-style-type:lower-roman}.yue ul{list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-left:1.625em}.yue ol>li::marker{font-weight:400;color:var(--yue-c-ol-marker)}.yue ul>li::marker{color:var(--yue-c-ul-marker)}.yue dl{margin-top:1.5rem;margin-bottom:1.5rem}.yue dt{color:var(--yue-c-bold);font-weight:600}.yue dd{margin-left:1.5rem}.yue hr{border-color:var(--yue-c-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.yue blockquote{color:var(--yue-c-quote);border-left-width:.25rem;border-left-color:var(--yue-c-quote-border);margin-top:1.2rem;margin-bottom:1.2rem;padding-left:1rem}.yue blockquote .attribution{font-size:.85em;font-style:italic}[lang=ja] .yue blockquote .attribution,[lang=ko] .yue blockquote .attribution,[lang^=zh] .yue blockquote .attribution{font-style:normal}.yue h1{color:var(--yue-c-heading);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.yue h1 strong{font-weight:900;color:inherit}.yue h2{color:var(--yue-c-heading);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.yue h2 strong{font-weight:800;color:inherit}.yue h3{color:var(--yue-c-heading);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.yue h3 strong{font-weight:700;color:inherit}.yue h4{color:var(--yue-c-heading);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.yue h4 strong{font-weight:700;color:inherit}.yue img{margin-top:2em;margin-bottom:2em}.yue figure>*{margin-top:0;margin-bottom:0}.yue figcaption{color:var(--yue-c-caption);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.yue code{color:var(--yue-c-code);font-weight:600;font-size:.875em}.yue a code,.yue blockquote code,.yue h1 code,.yue h2 code,.yue h3 code,.yue h4 code,.yue th code{color:inherit}.yue h2 code{font-size:.875em}.yue li>code,.yue p>code{padding-left:4px;padding-right:4px;border-radius:3px;font-weight:500;background-color:var(--yue-c-code-bg)}.yue h3 code{font-size:.9em}.yue figure,.yue video{margin-top:2em;margin-bottom:2em}.yue li{margin-top:.5em;margin-bottom:.5em}.yue ol>li,.yue ul>li{padding-left:.375em}.yue ol ol,.yue ol ul,.yue ul ol,.yue ul ul{margin-top:.75em;margin-bottom:.75em}.yue h2+*,.yue h3+*,.yue h4+*,.yue hr+*{margin-top:0}.yue table{width:100%;table-layout:auto;text-align:left;margin-top:2em;margin-bottom:2em;font-size:.86em;line-height:1.7}.yue table>caption{margin-bottom:.4rem;color:var(--yue-c-caption)}.yue thead tr{border-bottom-width:1px;border-bottom-color:var(--yue-c-th-border)}.yue thead th{color:var(--yue-c-heading);font-weight:600;vertical-align:middle}.yue tbody tr{border-bottom-width:1px;border-bottom-color:var(--yue-c-td-border)}.yue tbody tr:last-child{border-bottom-width:0}.yue tbody td{vertical-align:middle}.yue tfoot{border-top-width:1px;border-top-color:var(--yue-c-th-border)}.yue tfoot td{vertical-align:top}.yue td>p{margin:.25rem 0}.yue thead th>p{margin:0}.yue tbody td,.yue tfoot td,.yue thead th{padding:.5rem}.yue section>div{margin-bottom:2rem}.yue dd>p:first-child{margin-top:0}.yue p.lead{font-size:1.2rem;color:var(--sy-c-text-weak);margin-bottom:0}.yue p.lead+hr{margin-top:1rem}.yue p.rubric{color:var(--yue-c-heading);font-weight:600;font-size:1.25em;margin-top:2em}.yue dl.simple>dd>p,.yue ol.simple>li>p,.yue ul.simple>li>p{margin:0}.yue a.headerlink{visibility:hidden;margin-left:6px;color:rgba(var(--sy-rc-text),.6);font-weight:300;font-size:58%;font-family:var(--sy-f-mono);--icon-url:var(--i-link-url);-webkit-mask:var(--icon-url) no-repeat;mask:var(--icon-url) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;width:1em;height:1em;display:inline-block;vertical-align:middle;font-style:normal;background-color:currentColor}.yue .math a.headerlink,h1:hover a.headerlink,h2:hover a.headerlink,h3:hover a.headerlink,h4:hover a.headerlink,h5:hover a.headerlink,h6:hover a.headerlink{visibility:visible}.yue .toctree-wrapper a{border-bottom:none}.yue .toctree-wrapper p.caption{font-size:.86rem;font-weight:500;font-family:var(--sy-f-heading);color:var(--sy-c-text-weak);text-transform:uppercase;letter-spacing:.4px;padding:.8rem 0 .4rem;border-bottom:1px solid var(--sy-c-divider)}.yue .align-center{display:block;text-align:center}.yue .align-center,.yue figure.align-center img{margin-left:auto;margin-right:auto}a.footnote-reference{font-size:.65rem;vertical-align:top}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>p,div.citation>p{margin-bottom:.5rem;margin-top:.5rem;margin-left:2rem}.yue kbd.kbd:not(.compound){font-size:.86rem;padding:2px 5px;border-radius:3px;margin-right:.25rem}.yue kbd.compound>kbd{margin-left:.25rem}.light .yue kbd.kbd:not(.compound){background:linear-gradient(-225deg,#e6e6e6,#f8f8f8);box-shadow:inset 0 -2px #dbdbdb,inset 0 0 1px 1px #fff,0 1px 2px 1px #50505066}.dark .yue kbd.kbd:not(.compound){background:linear-gradient(-225deg,#353434,#141414);box-shadow:inset 0 -2px #373737,inset 0 0 1px 1px #222,0 1px 2px 1px #000}.hlist td{vertical-align:top}p.centered{text-align:center}.dark .light-only,.light .dark-only{display:none}.yue .genindex-jumpbox,.yue .modindex-jumpbox{border-top:1px solid var(--sy-c-border);border-bottom:1px solid var(--sy-c-border);padding:2px .4rem}.yue table.modindextable td:first-of-type{width:28px}.yue table.modindextable img.toggler{margin:0}.yue table.modindextable tr.cap{font-size:1.12rem;background:var(--sy-c-bg-weak);font-family:var(--sy-f-mono)}.yue h2+table.indextable,.yue table.indextable ul{margin-top:0}:root,html.light{--admonition-bg-opacity:0.03;--admonition-head-opacity:0.08;--admonition-border-opacity:1}@media (prefers-color-scheme:dark){:root{--admonition-bg-opacity:0.08;--admonition-head-opacity:0.15;--admonition-border-opacity:0.8}}html.dark{--admonition-bg-opacity:0.08;--admonition-head-opacity:0.15;--admonition-border-opacity:0.8}:root{--attention-icon:var(--i-alert-url);--attention-color:247,89,171;--caution-icon:var(--i-zap-url);--caution-color:247,186,42;--danger-icon:var(--i-skull-url);--danger-color:255,92,47;--error-icon:var(--i-close-url);--error-color:255,92,47;--hint-icon:var(--i-bell-url);--hint-color:0,200,80;--important-icon:var(--i-flame-url);--important-color:179,127,235;--note-icon:var(--i-calendar-url);--note-color:3,169,244;--tip-icon:var(--i-rocket-url);--tip-color:0,200,80;--warning-icon:var(--i-zap-url);--warning-color:255,145,0;--seealso-icon:var(--i-link-url);--seealso-color:60,140,255;--todo-icon:var(--i-bookmark-url);--todo-color:220,150,0;--versionadded-color:0,200,80;--versionchanged-color:247,186,42;--deprecated-color:255,92,47}.admonition{--color-rgb:var(--sy-rc-theme);--icon-url:var(--i-bell-url);position:relative;padding:0 16px .8rem;margin-top:1rem;margin-bottom:1rem;border-left:4px solid rgba(var(--color-rgb),var(--admonition-border-opacity));background-color:rgba(var(--color-rgb),var(--admonition-bg-opacity))}.admonition:before{position:absolute;content:"";top:6px;left:-12px;width:20px;height:20px;border-radius:100%;background-color:rgb(var(--color-rgb))}.admonition p.admonition-title{position:relative;margin:0 -16px .8rem -19px;padding:4px 18px;font-size:.85rem;font-weight:600;line-height:1.72;color:rgb(var(--color-rgb));background-color:rgba(var(--color-rgb),var(--admonition-head-opacity));--yue-c-code:rgb(var(--color-rgb));--yue-c-bold:rgb(var(--color-rgb))}.admonition p.admonition-title svg{display:inline-block}.admonition-title:before{position:absolute;content:"";top:10px;left:-5px;-webkit-mask:var(--icon-url) no-repeat;mask:var(--icon-url) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;font-style:normal;width:12px;height:12px;background-color:#fff}.admonition.attention{--icon-url:var(--attention-icon);--color-rgb:var(--attention-color)}.admonition.caution{--icon-url:var(--caution-icon);--color-rgb:var(--caution-color)}.admonition.danger{--icon-url:var(--danger-icon);--color-rgb:var(--danger-color)}.admonition.error{--icon-url:var(--error-icon);--color-rgb:var(--error-color)}.admonition.hint{--icon-url:var(--hint-icon);--color-rgb:var(--hint-color)}.admonition.important{--icon-url:var(--important-icon);--color-rgb:var(--important-color)}.admonition.note{--icon-url:var(--note-icon);--color-rgb:var(--note-color)}.admonition.tip{--icon-url:var(--tip-icon);--color-rgb:var(--tip-color)}.admonition.warning{--icon-url:var(--warning-icon);--color-rgb:var(--warning-color)}.admonition.seealso{--icon-url:var(--seealso-icon);--color-rgb:var(--seealso-color)}.admonition.admonition-todo{--icon-url:var(--todo-icon);--color-rgb:var(--todo-color)}.admonition p.admonition-title+p{margin-top:0}.admonition>:last-child{margin-bottom:0}span.versionmodified{color:var(--sy-c-bold);font-weight:600}div.deprecated,div.versionadded,div.versionchanged{--version-color:var(--sy-rc-theme);position:relative;padding:6px 1rem;margin:1rem 0;border-left:4px solid rgba(var(--version-color),1);background-color:rgba(var(--version-color),.08);line-height:1.72}div.deprecated:before,div.versionadded:before,div.versionchanged:before{position:absolute;content:var(--version-icon);top:10px;left:-12px;color:#fff;width:20px;height:20px;border-radius:100%;background-color:rgba(var(--version-color),1);text-align:center;font:normal 700 14px/20px var(--sy-f-mono)}div.versionadded{--version-color:var(--versionadded-color);--version-icon:"#"}div.versionchanged{--version-color:var(--versionchanged-color);--version-icon:"%"}div.deprecated{--version-color:var(--deprecated-color);--version-icon:"!"}div.deprecated>p,div.versionadded>p,div.versionchanged>p{margin:0}.yue blockquote.epigraph{padding:1rem 2.4rem;border-left:0;text-align:center}.yue blockquote.highlights{border-left-width:4px;padding-top:.2rem;padding-bottom:.2rem;background-color:var(--sy-c-bg-weak)}.yue blockquote.pull-quote{position:relative;font-size:1.24rem;padding:2.4rem 3.6rem 1.2rem;border-left:0}.yue blockquote.pull-quote:before{content:"\201c";position:absolute;top:0;left:.5rem;color:var(--yue-c-quote-symbol);font:700 4rem/1 Times New Roman,Georgia,Palatino,Times,serif}.yue blockquote.pull-quote .attribution{text-align:right}pre.literal-block{line-height:1.48;padding:1rem;font-size:.96rem;background-color:var(--syntax-pre-bg);border-radius:6px;overflow:auto}.highlight,.literal-block-wrapper{--margin:1rem;--radius:6px}.highlight>pre{line-height:1.48;padding:var(--margin);font-size:.96rem;font-family:var(--sy-f-mono);background-color:var(--syntax-pre-bg);border-radius:var(--radius);overflow:auto}.win .highlight>pre{font-family:"Twemoji Country Flags",var(--sy-f-mono)}.highlight .linenos{display:inline-block;box-shadow:-.05rem 0 rgba(var(--sy-rc-invert),.2) inset;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.8rem;padding-right:.8rem;opacity:.6}.highlight .hll{margin-left:calc(0rem - var(--margin));margin-right:calc(0rem - var(--margin));padding:0 var(--margin)}.code-block-caption{font-size:.84rem;font-weight:600;color:var(--syntax-text);background-color:var(--syntax-cap-bg);padding:.4rem var(--margin);border-radius:var(--radius) var(--radius) 0 0}.code-block-caption+div>.highlight>pre{border-top-left-radius:0;border-top-right-radius:0}div[class^=highlight]>.highlight>pre{display:grid}.yue .table-wrapper{width:100%;overflow-x:auto;margin-top:2rem;margin-bottom:2rem}.yue .table-wrapper>table{margin:0}.yue .table-wrapper thead tr{border-top:1px solid var(--yue-c-td-border)}.yue .table-wrapper th{background-color:var(--yue-c-th-bg);border-left:1px solid var(--yue-c-td-border)}.yue .table-wrapper td,.yue .table-wrapper th:last-child{border-right:1px solid var(--yue-c-td-border)}.yue .table-wrapper td{border-left:1px solid var(--yue-c-td-border)}.yue .table-wrapper tbody tr:first-child{border-top:1px solid var(--yue-c-td-border)}.yue .table-wrapper tbody tr:last-child{border-bottom-width:1px}.yue .table-wrapper thead+tbody tr:first-child{border-top-width:0}.yue table.hlist td{vertical-align:top}.table-wrapper{overflow-x:auto;scrollbar-gutter:stable}.table-wrapper::-webkit-scrollbar{height:.75rem;width:.75rem}.table-wrapper::-webkit-scrollbar-thumb{border-radius:10px}.table-wrapper::-webkit-scrollbar-track{background-color:initial}.table-wrapper:hover::-webkit-scrollbar-thumb{background-color:#9b9b9b33;background-clip:content-box;border:3px solid #0000}html.light{--sig-property:var(--syntax-light-keyword);--sig-name:var(--syntax-light-property);--sig-typehint:var(--syntax-light-constant)}html.dark{--sig-property:var(--syntax-dark-keyword);--sig-name:var(--syntax-dark-property);--sig-typehint:var(--syntax-dark-constant)}dt.sig{position:relative;font-size:.92rem;padding:.25rem .5rem .25rem 3rem;text-indent:-2.4rem;border-radius:6px}dt.sig:after{content:"";display:table;clear:both}dt.sig:hover{background:var(--sy-c-bg-weak)}dt.sig+dd{font-size:.92rem;margin-left:2rem}dt.sig>em.property:first-child{color:var(--sig-property)}dl.field-list a{font-weight:400}dt.sig+dd>div{margin-bottom:1rem}dt.sig+dd>dl.field-list>dt{text-transform:uppercase;font-size:.76rem}em.property,em.sig-param{font-style:normal}em.sig-param{color:var(--sy-c-text-weak)}span.sig-name,span.sig-prename{color:var(--sig-name)}span.sig-name{font-weight:600}span.sig-return-icon{color:var(--sy-c-text-weak)}span.sig-return-typehint,span.sig-return-typehint>a{color:var(--sig-typehint)}span.pre,span.sig-paren{font-family:var(--sy-f-mono)}dt.sig>a.internal{font-size:.82rem;border:0;color:var(--sy-c-text-weak)}dt.sig>a.internal:before{content:"\a";white-space:pre}.viewcode-block{position:relative}.viewcode-back{position:absolute;top:-1.5rem;font-size:.8rem}.classifier{font-style:oblique;font-weight:400}.classifier:before{font-style:normal;margin-left:.1rem;margin-right:.5rem;content:":";display:inline-block}.yue .table-wrapper table.autosummary td{border:none;padding-top:.25rem;padding-bottom:.25rem}.yue p.rubric+div.autosummary{margin-top:0}:root{--syntax-light-pre-bg:rgba(var(--sy-rc-theme),0.1);--syntax-light-cap-bg:rgba(var(--sy-rc-theme),0.2);--syntax-light-highlight-bg:rgba(var(--sy-rc-theme),0.2);--syntax-light-text:#24292f;--syntax-light-meta:#807c87;--syntax-light-comment:#6e7781;--syntax-light-constant:#0550ae;--syntax-light-entity:#268bd2;--syntax-light-property:#8250df;--syntax-light-definition:#24292f;--syntax-light-tag:#085;--syntax-light-builtin:#b58900;--syntax-light-keyword:#cf222e;--syntax-light-exception:#e6212e;--syntax-light-string:#0a3069;--syntax-light-regexp:#e40;--syntax-light-variable:#a4480f;--syntax-light-invalid-illegal-text:#f6f8fa;--syntax-light-invalid-illegal-bg:#82071e;--syntax-light-markup-heading:#0550ae;--syntax-light-markup-italic:#24292f;--syntax-light-markup-bold:#24292f;--syntax-light-markup-deleted-text:#82071e;--syntax-light-markup-deleted-bg:#ffebe9;--syntax-light-markup-inserted-text:#116329;--syntax-light-markup-inserted-bg:#dafbe1;--syntax-light-markup-changed-text:#953800;--syntax-light-markup-changed-bg:#ffd8b5;--syntax-light-markup-ignored-text:#eaeef2;--syntax-light-markup-ignored-bg:#0550ae;--syntax-light-meta-diff-range:#8250df;--syntax-light-special-bg:#dccafa;--syntax-dark-pre-bg:rgba(var(--sy-rc-theme),0.2);--syntax-dark-cap-bg:rgba(var(--sy-rc-theme),0.1);--syntax-dark-highlight-bg:rgba(var(--sy-rc-theme),0.2);--syntax-dark-text:#c9d1d9;--syntax-dark-meta:#6e7781;--syntax-dark-comment:#8b949e;--syntax-dark-constant:#79c0ff;--syntax-dark-entity:#47b0fa;--syntax-dark-property:#d2a8ff;--syntax-dark-definition:#c9d1d9;--syntax-dark-tag:#7ee787;--syntax-dark-builtin:#ffd34c;--syntax-dark-keyword:#ff7b72;--syntax-dark-exception:#da473c;--syntax-dark-string:#a5d6ff;--syntax-dark-regexp:#ef954e;--syntax-dark-variable:#ffa657;--syntax-dark-invalid-illegal-text:#f0f6fc;--syntax-dark-invalid-illegal-bg:#8e1519;--syntax-dark-markup-heading:#1f6feb;--syntax-dark-markup-italic:#c9d1d9;--syntax-dark-markup-bold:#c9d1d9;--syntax-dark-markup-deleted-text:#ffdcd7;--syntax-dark-markup-deleted-bg:#67060c;--syntax-dark-markup-inserted-text:#aff5b4;--syntax-dark-markup-inserted-bg:#033a16;--syntax-dark-markup-changed-text:#ffdfb6;--syntax-dark-markup-changed-bg:#5a1e02;--syntax-dark-markup-ignored-text:#c9d1d9;--syntax-dark-markup-ignored-bg:#1158c7;--syntax-dark-meta-diff-range:#d2a8ff;--syntax-dark-special-bg:#4f425d}:root,html.light{--syntax-pre-bg:var(--syntax-light-pre-bg);--syntax-cap-bg:var(--syntax-light-cap-bg);--syntax-highlight-bg:var(--syntax-light-highlight-bg);--syntax-text:var(--syntax-light-text);--syntax-meta:var(--syntax-light-meta);--syntax-comment:var(--syntax-light-comment);--syntax-constant:var(--syntax-light-constant);--syntax-entity:var(--syntax-light-entity);--syntax-property:var(--syntax-light-property);--syntax-definition:var(--syntax-light-definition);--syntax-tag:var(--syntax-light-tag);--syntax-builtin:var(--syntax-light-builtin);--syntax-keyword:var(--syntax-light-keyword);--syntax-exception:var(--syntax-light-exception);--syntax-string:var(--syntax-light-string);--syntax-regexp:var(--syntax-light-regexp);--syntax-variable:var(--syntax-light-variable);--syntax-invalid-illegal-text:var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-light-markup-heading);--syntax-markup-italic:var(--syntax-light-markup-italic);--syntax-markup-bold:var(--syntax-light-markup-bold);--syntax-markup-deleted-text:var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-light-meta-diff-range);--syntax-special-bg:var(--syntax-light-special-bg)}@media (prefers-color-scheme:dark){:root{--syntax-pre-bg:var(--syntax-dark-pre-bg);--syntax-cap-bg:var(--syntax-dark-cap-bg);--syntax-highlight-bg:var(--syntax-dark-highlight-bg);--syntax-text:var(--syntax-dark-text);--syntax-meta:var(--syntax-dark-meta);--syntax-comment:var(--syntax-dark-comment);--syntax-constant:var(--syntax-dark-constant);--syntax-entity:var(--syntax-dark-entity);--syntax-property:var(--syntax-dark-property);--syntax-definition:var(--syntax-dark-definition);--syntax-tag:var(--syntax-dark-tag);--syntax-builtin:var(--syntax-dark-builtin);--syntax-keyword:var(--syntax-dark-keyword);--syntax-exception:var(--syntax-dark-exception);--syntax-string:var(--syntax-dark-string);--syntax-regexp:var(--syntax-dark-regexp);--syntax-variable:var(--syntax-dark-variable);--syntax-invalid-illegal-text:var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-dark-markup-heading);--syntax-markup-italic:var(--syntax-dark-markup-italic);--syntax-markup-bold:var(--syntax-dark-markup-bold);--syntax-markup-deleted-text:var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-dark-meta-diff-range);--syntax-special-bg:var(--syntax-dark-special-bg)}}html.dark{--syntax-pre-bg:var(--syntax-dark-pre-bg);--syntax-cap-bg:var(--syntax-dark-cap-bg);--syntax-highlight-bg:var(--syntax-dark-highlight-bg);--syntax-text:var(--syntax-dark-text);--syntax-meta:var(--syntax-dark-meta);--syntax-comment:var(--syntax-dark-comment);--syntax-constant:var(--syntax-dark-constant);--syntax-entity:var(--syntax-dark-entity);--syntax-property:var(--syntax-dark-property);--syntax-definition:var(--syntax-dark-definition);--syntax-tag:var(--syntax-dark-tag);--syntax-builtin:var(--syntax-dark-builtin);--syntax-keyword:var(--syntax-dark-keyword);--syntax-exception:var(--syntax-dark-exception);--syntax-string:var(--syntax-dark-string);--syntax-regexp:var(--syntax-dark-regexp);--syntax-variable:var(--syntax-dark-variable);--syntax-invalid-illegal-text:var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-dark-markup-heading);--syntax-markup-italic:var(--syntax-dark-markup-italic);--syntax-markup-bold:var(--syntax-dark-markup-bold);--syntax-markup-deleted-text:var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-dark-meta-diff-range);--syntax-special-bg:var(--syntax-dark-special-bg)}.dark-code{--syntax-pre-bg:#2c283b;--syntax-cap-bg:#342f47;--syntax-highlight-bg:#423551;--syntax-text:var(--syntax-dark-text);--syntax-meta:var(--syntax-dark-meta);--syntax-comment:var(--syntax-dark-comment);--syntax-constant:var(--syntax-dark-constant);--syntax-entity:var(--syntax-dark-entity);--syntax-property:var(--syntax-dark-property);--syntax-definition:var(--syntax-dark-definition);--syntax-tag:var(--syntax-dark-tag);--syntax-builtin:var(--syntax-dark-builtin);--syntax-keyword:var(--syntax-dark-keyword);--syntax-exception:var(--syntax-dark-exception);--syntax-string:var(--syntax-dark-string);--syntax-regexp:var(--syntax-dark-regexp);--syntax-variable:var(--syntax-dark-variable);--syntax-invalid-illegal-text:var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-dark-markup-heading);--syntax-markup-italic:var(--syntax-dark-markup-italic);--syntax-markup-bold:var(--syntax-dark-markup-bold);--syntax-markup-deleted-text:var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-dark-meta-diff-range);--syntax-special-bg:var(--syntax-dark-special-bg)}.sy-lside{--height:42px}.sy-lside-bottom{position:sticky;bottom:0;padding:0;border-top:1px solid var(--sy-c-divider);background-color:var(--sy-c-bg);--tw-shadow:0 -12px 16px var(--sy-c-bg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.sy-lside .rst-versions{position:static;width:100%;background-color:var(--sy-c-bg-weak);font-family:var(--sy-f-text)}.sy-lside .rst-versions a{color:var(--sy-c-link)}.sy-lside .rst-versions .rst-current-version{background-color:var(--sy-c-bg);color:var(--sy-c-text);padding:0 1rem;height:var(--height);line-height:var(--height)}.sy-lside .rst-versions.rst-badge .rst-current-version{text-align:left;font-size:.94rem;padding:0 1rem;height:var(--height);line-height:var(--height)}.sy-lside .rst-versions .rst-current-version .fa{color:var(--sy-c-text)}.sy-lside .rst-versions.rst-badge.shift-up .rst-current-version{text-align:left}.sy-lside .rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:none}.sy-lside .rst-other-versions{font-size:.86rem;border-top:1px solid var(--sy-c-divider)}.sy-lside .rst-other-versions dt{font-size:.68rem;font-weight:500;padding:4px 6px;color:var(--sy-c-text-weak)}.sy-lside .rst-versions .rst-other-versions dd a{color:var(--sy-c-text)}.sy-lside .rst-versions .rst-other-versions dd a:hover{text-decoration:underline;color:var(--sy-c-link)}.sy-lside .rst-versions input{width:100%;padding:6px 12px;font-size:.92rem;font-family:var(--sy-f-text);border-radius:6px;outline:0;background:var(--sy-c-bg);border:1px solid var(--sy-c-border)}.sy-lside .rst-versions .rst-other-versions hr{border-color:var(--sy-c-divider)}@media (min-width:90rem){.sy-lside .rst-versions{background:var(--sy-c-bg)}}.yue button.copybtn{align-items:center;justify-content:center;background-color:initial;border:none;color:var(--syntax-text)}.yue button.copybtn>svg{width:1.4rem;height:1.4rem}.yue .highlight button.copybtn:hover{background-color:initial;color:var(--syntax-meta)}.yue .o-tooltip--left:after{background-color:initial;color:var(--syntax-text)}.yue{--sd-color-primary:rgb(var(--sy-rc-theme));--sd-color-success:#00c850;--sd-color-warning:#ff9100;--sd-color-danger:#ff5c2f;--sd-color-card-border-hover:var(--sy-c-border);--sd-color-card-border:var(--sy-c-divider);--sd-color-tabs-label-inactive:var(--sy-c-bold);--sd-color-tabs-label-active:var(--sd-color-primary);--sd-color-tabs-underline-active:var(--sd-color-primary)}.light .yue{--sd-color-shadow:#f3f4f6}.dark .yue{--sd-color-shadow:#010409}.yue .sd-container-fluid{margin-top:2rem;padding:.5rem}.yue .sd-row{--sd-gutter-x:1rem;--sd-gutter-y:1rem}.yue .sd-row-cols-1{display:grid;grid-template-columns:1fr;grid-gap:1rem}.yue .sd-row-cols-2{display:grid;grid-template-columns:1fr 1fr;grid-gap:1rem}.yue .sd-row-cols-1>.sd-col,.yue .sd-row-cols-2>.sd-col{width:100%;padding:0;margin:0}.yue .sd-card-hover:hover{transform:scale(1)}.yue .sd-card-hover:hover .sd-card-title{color:var(--sy-c-link)}.yue .sd-card a,.yue .sd-card a:hover{border-bottom:0}@media (max-width:880px){.yue .sd-row-cols-2{grid-template-columns:1fr}}.yue .sd-tab-set>label{padding:1rem .25rem .5rem;font-size:.84rem;font-weight:500}.yue .sd-tab-set>label~label{margin-left:1rem}.yue .sd-tab-content{padding:0;box-shadow:0 -.0625rem var(--sy-c-divider)}.light .sd-tab-content .highlight{--syntax-pre-bg:var(--syntax-light-pre-bg);--syntax-cap-bg:var(--syntax-light-cap-bg);--syntax-text:var(--syntax-light-text);--syntax-meta:var(--syntax-light-meta);--syntax-comment:var(--syntax-light-comment);--syntax-constant:var(--syntax-light-constant);--syntax-entity:var(--syntax-light-entity);--syntax-property:var(--syntax-light-property);--syntax-definition:var(--syntax-light-definition);--syntax-tag:var(--syntax-light-tag);--syntax-builtin:var(--syntax-light-builtin);--syntax-keyword:var(--syntax-light-keyword);--syntax-exception:var(--syntax-light-exception);--syntax-string:var(--syntax-light-string);--syntax-regexp:var(--syntax-light-regexp);--syntax-variable:var(--syntax-light-variable);--syntax-invalid-illegal-text:var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-light-markup-heading);--syntax-markup-italic:var(--syntax-light-markup-italic);--syntax-markup-bold:var(--syntax-light-markup-bold);--syntax-markup-deleted-text:var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-light-meta-diff-range);--syntax-highlight-bg:var(--syntax-light-highlight-bg);--syntax-special-bg:var(--syntax-light-special-bg)}.yue .sd-tab-content .highlight pre{border-radius:0}@media (print){.yue .sd-card{page-break-inside:avoid}}.yue a.sd-text-wrap{border-bottom:0}.sphinx-tabs [role=tablist]{border-color:var(--sy-c-divider)}.yue .sphinx-tabs-tab{color:var(--sy-c-text);line-height:inherit;padding:1rem .25rem .5rem;font-size:.84rem;font-weight:500;border:none;border-bottom:.125rem solid #0000}.yue .sphinx-tabs-tab:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.yue .sphinx-tabs-tab[aria-selected=true]{border:none;border-bottom:.125rem solid var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active);background-color:initial}.yue .sphinx-tabs-tab+.sphinx-tabs-tab{margin-left:1rem}.yue .sphinx-tabs-panel{border:none;padding:0;margin:0;border-radius:0;background-color:initial}.yue .sphinx-tabs-panel.code-tab{padding:0}.yue .sphinx-tabs-panel.code-tab .highlight pre{border-radius:0}.yue .jupyter_container{background-color:var(--sy-c-bg);border:3px solid var(--sy-c-border);border-radius:6px;overflow:hidden;box-shadow:none}.document .yue .jupyter_container div[class^=highlight]{padding:0}.yue .jupyter_container div.cell_input{background-color:var(--syntax-pre-bg);border:0;border-radius:0}.yue .jupyter_container div.code_cell pre{padding:0}.jupyter_container div.cell_output>.output,.jupyter_container div.cell_output>.stderr,.jupyter_container div.cell_output>.thebelab-output,.jupyter_container div.cell_output>.widget-subarea{padding:.5rem}.jupyter_container div.code_cell .highlight>pre{padding:1rem}.jupyter_container div.code_cell .highlight .hll{margin-left:-1rem;margin-right:-1rem;padding:0 1rem}.jupyter_container div.code_cell .highlight .linenos{margin-right:.8rem}.yue .jupyter_container .stderr{background-color:var(--stderr-bg)}html.light .stderr{--stderr-bg:#ff8d8d}html.dark .stderr{--stderr-bg:#e02323}html.light .jupyter_container .cell_output{--syntax-pre-bg:var(--syntax-light-pre-bg);--syntax-cap-bg:var(--syntax-light-cap-bg);--syntax-text:var(--syntax-light-text);--syntax-meta:var(--syntax-light-meta);--syntax-comment:var(--syntax-light-comment);--syntax-constant:var(--syntax-light-constant);--syntax-entity:var(--syntax-light-entity);--syntax-property:var(--syntax-light-property);--syntax-definition:var(--syntax-light-definition);--syntax-tag:var(--syntax-light-tag);--syntax-builtin:var(--syntax-light-builtin);--syntax-keyword:var(--syntax-light-keyword);--syntax-exception:var(--syntax-light-exception);--syntax-string:var(--syntax-light-string);--syntax-regexp:var(--syntax-light-regexp);--syntax-variable:var(--syntax-light-variable);--syntax-invalid-illegal-text:var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-light-markup-heading);--syntax-markup-italic:var(--syntax-light-markup-italic);--syntax-markup-bold:var(--syntax-light-markup-bold);--syntax-markup-deleted-text:var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-light-meta-diff-range);--syntax-highlight-bg:var(--syntax-light-highlight-bg);--syntax-special-bg:var(--syntax-light-special-bg)}.nbinput .highlight{--radius:1px}.yue div.nblast.container{padding-top:5px}.yue div.nbinput.container div.input_area{border-color:var(--sy-c-border)}.yue div.nboutput.container div.output_area.stderr{background-color:var(--stderr-bg)}.yue div.nboutput.container div.output_area>.math-wrapper>div.math{padding-top:0}@media print{.print\:hidden{display:none}.print\:pt-6{padding-top:1.5rem}}@media not all and (min-width:640px){.max-sm\:max-w-full{max-width:100%}}@media (min-width:768px){.md\:sticky{position:sticky}.md\:inline{display:inline}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-72{width:18rem}.md\:shrink-0{flex-shrink:0}}@media (min-width:1280px){.xl\:sticky{position:sticky}.xl\:top-16{top:4rem}.xl\:hidden{display:none}.xl\:px-12{padding-left:3rem;padding-right:3rem}.xl\:pl-0{padding-left:0}} \ No newline at end of file diff --git a/_static/shibuya.js b/_static/shibuya.js new file mode 100644 index 00000000..fce65719 --- /dev/null +++ b/_static/shibuya.js @@ -0,0 +1 @@ +(()=>{function y(t){let e=t.getAttribute("aria-controls"),s=document.getElementById(e),c="data-expanded-"+e;t.addEventListener("click",function(){document.body.hasAttribute(c)?(document.body.removeAttribute(c),s.classList.remove("_expanded"),m(e,"false")):(document.body.setAttribute(c,"true"),s.classList.add("_expanded"),m(e,"true"))})}function m(t,e){let s=document.querySelectorAll('[aria-controls="'+t+'"]');for(el of s)el.setAttribute("aria-expanded",e)}var f=document.querySelectorAll(".js-menu");for(let t=0;t{r.parentNode.removeChild(r),document.head.removeChild(t)}),e(),window.addEventListener("resize",e)}var L;var v=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches,d=document.documentElement;function A(){let t=d.classList.contains("dark"),e=t?"dark":"light";d.classList.remove(e);let s=t?"light":"dark";h(s),sessionStorage._theme=s}var i=document.querySelector(".js-theme");function h(t){d.classList.add(t);let e=i.getAttribute("data-aria-"+t);i.setAttribute("aria-label",e)}if(i){let t=v?"dark":"light",e=sessionStorage._theme||t;h(e),i.addEventListener("click",A)}function x(){let t=document.querySelector(".globaltoc");if(!t)return;let e=parseInt(t.getAttribute("data-expand-depth"),10),s=n=>{if(!e)return!1;let o=0;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode,n.nodeName==="UL"&&(o+=1);return e>=o};t.querySelectorAll("li > ul").forEach(n=>{let o=n.parentNode;o.classList.contains("current")||s(o)?o.classList.add("_expand"):o.classList.add("_collapse");let a=_(n);o.appendChild(a)})}function _(t){let e=document.createElement("button");e.innerHTML='';let s=t.parentNode,c=t.previousSibling,n=c.textContent,o=()=>{s.classList.contains("_expand")?e.setAttribute("arial-label","Collapse "+n):e.setAttribute("arial-label","Expand "+n)};o();let a=g=>{g.preventDefault(),s.classList.contains("_expand")?(s.classList.remove("_expand"),s.classList.add("_collapse")):(s.classList.remove("_collapse"),s.classList.add("_expand")),o()};return c.getAttribute("href")==="#"&&c.addEventListener("click",a),e.addEventListener("click",a),e}x();function b(){let t='.localtoc a[href="'+location.hash+'"]',e=document.querySelector(t);e&&(document.querySelectorAll(".localtoc li").forEach(c=>{c.classList.remove("active")}),e.parentNode.classList.add("active"))}b();window.addEventListener("hashchange",()=>{b()},!1);var l=document.querySelector(".js-repo-stats");async function w(t,e){let s=`https://api.github.com/repos/${t}/${e}`,n=await(await fetch(s)).json(),o={stars:n.watchers,forks:n.forks};u(o),sessionStorage.setItem("_sy/repo/stats",JSON.stringify(o))}async function E(t,e){let s="https://gitlab.com/api/v4/projects/"+encodeURIComponent(t+"/"+e),n=await(await fetch(s)).json(),o={stars:n.star_count,forks:n.forks_count};u(o),sessionStorage.setItem("_sy/repo/stats",JSON.stringify(o))}function u({stars:t,forks:e}){t&&(document.querySelector(".js-repo-stars").textContent=t),e&&(document.querySelector(".js-repo-forks").textContent=e)}function k(){let t=sessionStorage.getItem("_sy/repo/stats");if(t)u(JSON.parse(t));else{let e=l.getAttribute("data-user"),s=l.getAttribute("data-repo"),c=l.getAttribute("data-type");c==="github"?w(e,s):c==="gitlab"&&E(e,s)}}l&&k();function q(t,e){let s=document.createElement("script");s.id="_carbonads_js",s.src=`//cdn.carbonads.com/carbon.js?serve=${t}&placement=${e}`;let c=document.querySelector(".yue > section"),n=document.querySelector(".yue > section > section");if(n)c.insertBefore(s,n);else{let o=document.querySelector(".yue > section > p");o?c.insertBefore(s,o.nextSibling):c.appendChild(s)}}var p=document.querySelector(".js-carbon");if(p){let t=p.getAttribute("data-carbon-code"),e=p.getAttribute("data-carbon-placement");t&&e&&q(t,e)}/windows/i.test(navigator.userAgent)&&document.body.classList.add("win");})(); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 00000000..aae669d7 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,144 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '

" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(SphinxHighlight.highlightSearchWords); +_ready(SphinxHighlight.initEscapeListener); diff --git a/architecture.html b/architecture.html new file mode 100644 index 00000000..9145e6e1 --- /dev/null +++ b/architecture.html @@ -0,0 +1,321 @@ + + + + + + Arroyo Architecture - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Arroyo Architecture

+

Arroyo is a set of high level abstractions to interact with Kafka. +These are meant to help the developer in writing performant consumers with +specific delivery guarantees.

+

Common problems addressed by Arroyo are guaranteeing at-least-once delivery, +providing a dead letter queue abstraction, support parallel (multi-processing) +message processing, etc.

+

The library is divided into three layers: the basic Kafka connectivity, the +streaming engine and the high level abstractions.

+

The basic connectivity layer is a simple wrapper around the Confluent python +library, which is itself based on librdkafka. Besides some cosmetic changes, +this level provides a Fake in memory broker and consumer to make unit test quick +to run.

+

The streaming engine provides an asynchronous processing interface to write +consumers. The consumer is written as a pipeline where each segment is an +asynchronous operation. The streaming engine implements the main consumer loop +and delegates the processing to the pipeline.

+

On top of the streaming engine, the library provides high-level abstractions that +are common when writing Kafka consumers like: map, reduce, filter together +with some common messaging application patterns like the dead letter queue.

+
+

Streaming Interface and Streaming Engine

+

A Kafka consumer is built as a pipeline where each segment processes messages in +an asynchronous way. The Streaming engine provides a message to a segment. The +segment is not supposed to execute small CPU work in a blocking way or do IO in a +non-blocking way. We generally use futures for this, and heavier CPU work in a +separate process.

+

Arroyo provides an interface to implement to write a pipeline segment. +The segment interface is called ProcessingStrategy and is in +this module. +(TODO: bring the docstrings to the docs and reference that).

+

In most cases, when developing a consumer, the developer would not implement +that interface directly. A higher level abstraction would be used.

+
+_images/arroyo_processing.png +
+

The main consumer loop is managed by the stream engine. +These are the phases:

+
    +
  • Poll from the Kafka consumer through the basic library. If a message is there +proceed or repeat.

  • +
  • Submit the message to the first ProcessingStrategy. This is supposed to deliver +work for the strategy to do. It is not supposed to be a blocking operation. The +strategy should return immediately.

  • +
  • Poll the strategy to execute work or to forward results to the following step +in the pipeline. Ideally all IO should be done in separate threads and heavy cpu +work should be done in separate processes so the poll method should check for +completed work, dispatch to the next step and return. In practice, work is executed +here in a blocking way if the overhead of offloading the work is too high.

  • +
+

The ProcessingStrategy may decide not to take the message and instead apply back-pressure. +This is done by raising the MessageRejected exception. In this case, the streaming +engine pauses the consumer till the strategy is ready to accept the message.

+

The ProcessingStrategy decides when it is time to commit a message. This is done +through a commit callback provided to the strategy when it is instantiated.

+

The streaming engine orchestrates the life cycle of the ProcessingStrategy, thus +when it thinks it is time to shut the strategy down it would wait for all in-flight +work to be completed and then destroy the strategy.

+

There are two scenarios where this can happen:

+
    +
  • The consumer is being terminated.

  • +
  • A rebalancing happened. A rebalancing revokes partitions and assigns new ones. +After a rebalancing is complete it is impossible to commit a message from a partition +that was revoked. In order to ensure the consumer behaves in a consistent way, +upon rebalancing, the streaming engine destroys the strategy and builds a new one. +This allows the strategy to complete all in-flight work before being terminated.

  • +
+
+
+

High level strategies

+

Most consumers follow the same few patterns, so Arroyo provides abstractions that +are based on the ProcessingStrategy but are simpler to implement for the common +use cases.

+

Common examples are:

+
    +
  • run task, run task in threads, run task with multiprocessing. The run task +set of strategies are designed to be the most flexible and simple to use. They take +a function provided by the user and execute it on every message, passing the output +to the next step. The library includes synchronous and asynchronous versions depending +on the kind of concurrency required by the user.

  • +
  • filter, map and forward. This type of consumer inspects a message, decides +whether to process it or discard it, transforms its content, and produces the result +on a new topic. In this case, Arroyo provides three implementations of the +ProcessingStrategy: filter, transform, and produce. The developer only needs +to wire them together and provide the map and filtering logic.

  • +
  • consume, apply side effects, produce. This is a variation of the one above. +In this case, the transform operation can have side-effects like storing the content +of the message somewhere.

  • +
  • high throughput cpu intensive transform. The python GIL does not allow CPU intensive +work to take advantage of parallelism. Arroyo provides an implementation of the map +pattern that batches messages and dispatches the work to separate processes via shared +memory. This is largely transparent to the developers.

  • +
  • map, reduce and store. The reduce function is carried out by the Collector, which +batches messages and executes some logic with side-effects when the batch is full. +This is a typical way to write messages on a storages in batches to reduce the +round trips.

  • +
+

All strategies included with Arroyo are in the strategies module.

+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/backpressure.html b/backpressure.html new file mode 100644 index 00000000..d77c30a6 --- /dev/null +++ b/backpressure.html @@ -0,0 +1,249 @@ + + + + + + Backpressure - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Backpressure

+

Arroyo’s own processing strategies internally apply backpressure by raising +MessageRejected. Most +consumers do not require additional work to deal with backpressure correctly.

+

If you want to slow down the consumer based on some external signal or +condition, you can achieve that most effectively by raising the same exception +from within a callback passed to RunTask while the +consumer is supposed to be paused

+
class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    def __init__(self):
+        self.is_paused = False
+
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]:
+            if self.is_paused:
+                raise MessageRejected()
+
+            print(f"MSG: {message.payload}")
+            return message
+
+        return RunTask(handle_message, CommitOffsets(commit))
+
+
+

It is not recommended to apply backpressure by just sleep()-ing in +submit (or, in this example, +handle_message) for more than a few milliseconds. While this definitely +pauses the consumer, it will block the main thread for too long and and prevent +things like consumer rebalancing from occuring.

+

A 0.01 second sleep is applied each time MessageRejected is +raised to prevent the main thread spinning at 100% CPU. However background thread +performance may be impacted during this time.

+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dlqs.html b/dlqs.html new file mode 100644 index 00000000..93d88c8f --- /dev/null +++ b/dlqs.html @@ -0,0 +1,283 @@ + + + + + + Dead letter queues - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Dead letter queues

+
+

Warning

+

Dead letter queues should be used with caution as they break some of the ordering guarantees +otherwise offered by Arroyo and Kafka consumer code. In particular, it must be safe for the +consumer to drop a message. If replaying or later re-processing of the DLQ’ed messages is done, +it is critical that ordering is not a requirement in the relevant downstream code.

+
+

Arroyo provides support for routing invalid messages to dead letter queues in consumers. +Dead letter queues are critical in some applications because messages are ordered in Kafka +and a single invalid message can cause a consumer to crash and every subsequent message to +not be processed.

+

The dead letter queue configuration is passed to the StreamProcessor and, if provided, any +InvalidMessage raise by a strategy will be produced to the dead letter queue.

+
+
+class arroyo.dlq.DlqLimit(max_invalid_ratio: float | None = None, max_consecutive_count: int | None = None)
+

Defines any limits that should be placed on the number of messages that are +forwarded to the DLQ. This exists to prevent 100% of messages from going into +the DLQ if something is misconfigured or bad code is deployed. In this scenario, +it may be preferable to stop processing messages altogether and deploy a fix +rather than rerouting every message to the DLQ.

+

The ratio and max_consecutive_count are counted on a per-partition basis.

+
+ +
+
+class arroyo.dlq.DlqPolicy(producer: DlqProducer[TStrategyPayload], limit: DlqLimit | None = None, max_buffered_messages_per_partition: int | None = None)
+

DLQ policy defines the DLQ configuration, and is passed to the stream processor +upon creation of the consumer. It consists of the DLQ producer implementation and +any limits that should be applied.

+
+ +
+
+exception arroyo.dlq.InvalidMessage(partition: Partition, offset: int, needs_commit: bool = True)
+

InvalidMessage should be raised if a message is not valid for processing and +should not be retried. It will be placed a DLQ if one is configured.

+

It can be raised from the submit, poll or join methods of any processing strategy.

+

Once a filtered message is forwarded to the next step, needs_commit should be set to False, +in order to prevent multiple filtered messages from being forwarded for a single invalid message.

+
+ +
+
+class arroyo.dlq.KafkaDlqProducer(producer: Producer[KafkaPayload], topic: Topic)
+

KafkaDLQProducer forwards invalid messages to a Kafka topic

+

Two additional fields are added to the headers of the Kafka message +“original_partition”: The partition of the original message +“original_offset”: The offset of the original message

+
+ +
+
+class arroyo.dlq.NoopDlqProducer(*args, **kwds)
+

Drops all invalid messages

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 00000000..82cffd75 --- /dev/null +++ b/genindex.html @@ -0,0 +1,551 @@ + + + + + + Index - Arroyo documentation + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+
+ + +

Index

+ +
+ A + | B + | C + | D + | F + | G + | H + | I + | J + | K + | M + | N + | O + | P + | R + | S + | T + | U + | V + +
+

A

+ + + +
    +
  • + arroyo.dlq + +
  • +
  • + arroyo.processing.strategies.abstract + +
  • +
  • + arroyo.processing.strategies.batching + +
  • +
  • + arroyo.processing.strategies.commit + +
  • +
  • + arroyo.processing.strategies.filter + +
  • +
  • + arroyo.processing.strategies.healthcheck + +
  • +
  • + arroyo.processing.strategies.produce + +
  • +
    +
  • + arroyo.processing.strategies.reduce + +
  • +
  • + arroyo.processing.strategies.run_task + +
  • +
  • + arroyo.processing.strategies.run_task_in_threads + +
  • +
  • + arroyo.processing.strategies.run_task_with_multiprocessing + +
  • +
  • + arroyo.processing.strategies.unfold + +
  • +
  • + arroyo.types + +
  • +
  • + arroyo.utils.metrics + +
  • +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

F

+ + + +
+ +

G

+ + +
+ +

H

+ + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + +
+ +

M

+ + +
+ +

N

+ + + +
+ +

O

+ + +
+ +

P

+ + + +
+ +

R

+ + + +
+ +

S

+ + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/getstarted.html b/getstarted.html new file mode 100644 index 00000000..9bb4f027 --- /dev/null +++ b/getstarted.html @@ -0,0 +1,427 @@ + + + + + + Getting started with Arroyo - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Getting started with Arroyo

+

This tutorial shows how to create a Kafka consumer with Arroyo from scratch.

+
+

Setup

+

This section explains how to setup Kafka, Zookeeper and install the library

+
+

Kafka and Zookeeper

+

In order to run an arroyo Kafka consumer you will need a working Kafka broker. +If you already have one, you can skip this step. +If you do not have a running Kafka broker, this command will install and start +a Kafka docker container. (It requires Docker to be installed).

+
docker network create arroyo
+
+docker run --rm \
+    -v zookeeper_volume:/var/lib/zookeeper \
+    --env ZOOKEEPER_CLIENT_PORT=2181 \
+    --name=sentry_zookeeper \
+    --network=arroyo \
+    -p 2181:2181 \
+    confluentinc/cp-zookeeper:6.2.0
+
+docker run --rm \
+    -v kafka_volume:/var/lib/kafka \
+    --env KAFKA_ZOOKEEPER_CONNECT=sentry_zookeeper:2181 \
+    --env KAFKA_LISTENERS=INTERNAL://0.0.0.0:9093,EXTERNAL://0.0.0.0:9092 \
+    --env KAFKA_ADVERTISED_LISTENERS=INTERNAL://127.0.0.1:9093,EXTERNAL://127.0.0.1:9092 \
+    --env KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT \
+    --env KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL \
+    --env KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \
+    --env CONFLUENT_SUPPORT_METRICS_ENABLE=false \
+    --env KAFKA_LOG4J_LOGGERS=kafka.cluster=WARN,kafka.controller=WARN,kafka.coordinator=WARN,kafka.log=WARN,kafka.server=WARN,kafka.zookeeper=WARN,state.change.logger=WARN \
+    --env KAFKA_LOG4J_ROOT_LOGLEVEL=WARN \
+    --env KAFKA_TOOLS_LOG4J_LOGLEVEL=WARN \
+    --name=sentry_kafka \
+    --network=arroyo \
+    -p 9092:9092 \
+    confluentinc/cp-kafka:6.2.0
+
+
+

Now you should see Kafka and Zookeeper running with

+
docker ps
+
+
+
+
+

Install Kafkacat

+

This tool will be useful to produce onto and consume from topics.

+
https://docs.confluent.io/platform/current/app-development/kafkacat-usage.html#kcat-formerly-kafkacat-utility
+
+
+
+
+

Development environment

+

You will need to install the library. Most likely in a python venv. So first, create a python virtual +environment. Then you can install arroyo with this.

+
pip install sentry-arroyo
+
+
+
+
+

Create two Kafka topics

+

Our example will consume from one topic and produce the same messages on another topic. So we need +two topics.

+
docker exec sentry_kafka kafka-topics \
+    --create \
+    --topic source-topic \
+    --bootstrap-server 127.0.0.1:9092
+
+docker exec sentry_kafka kafka-topics \
+    --create \
+    --topic dest-topic \
+    --bootstrap-server 127.0.0.1:9092
+
+
+

Now you should be ready to develop with Arroyo.

+
+
+
+

Create a basic consumer

+

Arroyo provides two level of abstractions when writing a consumer: the basic consumer/producer library +and the Streaming library. The first is just a thin wrapper around a librdkafka consumer/producer that +adds some features around offset management. The second provides a more abstract streaming interface +that hides details like rebalancing and the consumer lifecycle.

+
+

Creating a basic consumer

+

This initializes a basic consumer and consumes a message.

+
from arroyo.backends.kafka.configuration import (
+    build_kafka_consumer_configuration,
+)
+from arroyo.backends.kafka.consumer import KafkaConsumer
+from arroyo.types import Topic
+
+TOPIC = Topic("source-topic")
+
+consumer = KafkaConsumer(
+    build_kafka_consumer_configuration(
+        default_config={},
+        bootstrap_servers=["127.0.0.1:9092"],
+        auto_offset_reset="latest",
+        group_id="test-group",
+    )
+)
+
+consumer.subscribe([TOPIC])
+
+while True:
+    msg = consumer.poll(timeout=1.0)
+    if msg is not None:
+        print(f"MSG: {msg.payload}")
+
+
+

Start this script and use kcat to produce a message:

+
echo "MESSAGE" | kcat -P -b 127.0.0.1:9092 -t source-topic
+
+
+

In a while the message should appear on the console:

+
MSG: KafkaPayload(key=None, value=b'MESSAGE', headers=[])
+
+
+
+
+

Create a streaming consumer

+

Add a ProcessingStrategy and ProcessingStrategyFactory. +Here we are using the RunTask strategy which runs a custom function over each message.

+
def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]:
+    print(f"MSG: {message.payload}")
+    return message
+
+class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    """
+    The factory manages the lifecycle of the `ProcessingStrategy`.
+    A strategy is created every time new partitions are assigned to the
+    consumer, while it is destroyed when partitions are revoked or the
+    consumer is closed
+    """
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        return RunTask(handle_message, CommitOffsets(commit))
+
+
+

The code above is orchestrated by the Arroyo runtime called StreamProcessor.

+
processor = StreamProcessor(
+    consumer=consumer,
+    topic=TOPIC,
+    processor_factory=ConsumerStrategyFactory(),
+)
+
+processor.run()
+
+
+

The main consumer loop is managed by the StreamProcessor no need to periodically poll the +consumer. The ConsumerStrategy works by inversion of control.

+
+
+

Add some useful logic

+

Now we will chain the Produce strategy to produce messages on a second topic after the message is logged

+
class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    """
+    The factory manages the lifecycle of the `ProcessingStrategy`.
+    A strategy is created every time new partitions are assigned to the
+    consumer, while it is destroyed when partitions are revoked or the
+    consumer is closed
+    """
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        producer = KafkaProducer(
+            build_kafka_configuration(
+                default_config={},
+                bootstrap_servers=BOOTSTRAP_SERVERS,
+            )
+        )
+
+        return RunTask(
+            handle_message,
+            Produce(producer, Topic("dest-topic"), CommitOffsets(commit))
+        )
+
+
+

The message is first passed to the RunTask strategy which simply logs the message and submits +the output to the next step. The Produce strategy produces the message asynchronously. Once +the message is produced, the CommitOffsets strategy commits the offset of the message.

+
+
+
+

Further examples

+

Find some complete examples of usage.

+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..c902b63b --- /dev/null +++ b/index.html @@ -0,0 +1,228 @@ + + + + + + Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+ _images/arroyo-banner.png +

Arroyo is a library to build streaming applications that consume from +and produce to Kafka.

+

It relies on the confluent_kafka python library, which itself relies +on librdkafka.

+

Arroyo provides mainly three functionalities:

+
    +
  • A set of abstractions inspired to common messaging applications patterns.

  • +
  • Some abstractions to simplify offset management and rebalancing.

  • +
  • An in memory broker abstraction to simplify writing unit tests.

  • +
+
+

Contents:

+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/intro.html b/intro.html new file mode 100644 index 00000000..65a54197 --- /dev/null +++ b/intro.html @@ -0,0 +1,205 @@ + + + + + + <no title> - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+ _images/arroyo-banner.png +

Arroyo is a library to build streaming applications that consume from +and produce to Kafka.

+

It relies on the confluent_kafka python library, which itself relies +on librdkafka.

+

Arroyo provides mainly three functionalities:

+
    +
  • A set of abstractions inspired to common messaging applications patterns.

  • +
  • Some abstractions to simplify offset management and rebalancing.

  • +
  • An in memory broker abstraction to simplify writing unit tests.

  • +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/metrics.html b/metrics.html new file mode 100644 index 00000000..56fd91c4 --- /dev/null +++ b/metrics.html @@ -0,0 +1,366 @@ + + + + + + Metrics - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Metrics

+

Arroyo consumers and strategies attempt to auto instrument some metrics that most people find useful +to understand the behavior and performance of their consumers. These metrics are typically sampled or +buffered as appropriate and flushed periodically (often once per second).

+

In order to use these metrics, you must configure a metrics backend that conforms to the metrics protocol +before creating your consumer.

+

This can be done like so:

+
from arroyo.utils.metrics import Metrics, MetricName
+
+ class MyMetrics(Metrics):
+     def increment(
+         self, name: MetricName, value: Union[int, float] = 1, tags: Optional[Tags] = None
+     ) -> None:
+         # Increment a counter by the given value.
+         record_incr(name, value, tags)
+
+     def gauge(
+         self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None
+     ) -> None:
+         # Sets a gauge metric to the given value.
+         record_gauge(name, value, tags)
+
+     def timing(
+         self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None
+     ) -> None:
+         # Emit a timing metric with the given value.
+         record_timing(name, value, tags)
+
+ metrics_backend = MyMetrics()
+
+ configure_metrics(metrics_backend)
+
+
+
+

Available Metrics

+
from typing import Literal
+
+MetricName = Literal[
+    # Number of messages in a multiprocessing batch
+    "arroyo.strategies.run_task_with_multiprocessing.batch.size.msg",
+    # Number of bytes in a multiprocessing batch
+    "arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes",
+    # Number of messages in a multiprocessing batch after the message transformation
+    "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.msg",
+    # Number of bytes in a multiprocessing batch after the message transformation
+    "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.bytes",
+    # Number of times the consumer is spinning
+    "arroyo.consumer.run.count",
+    # Number of times the consumer encounted an invalid message.
+    "arroyo.consumer.invalid_message.count",
+    # How long it took the Reduce step to fill up a batch
+    "arroyo.strategies.reduce.batch_time",
+    # Counter, incremented when a strategy after multiprocessing applies
+    # backpressure to multiprocessing. May be a reason why CPU cannot be
+    # saturated.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.backpressure",
+    # Counter, incremented when multiprocessing cannot fill the input batch
+    # because not enough memory was allocated. This results in batches smaller
+    # than configured. Increase `input_block_size` to fix.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow",
+    # Counter, incremented when multiprocessing cannot pull results in batches
+    # equal to the input batch size, because not enough memory was allocated.
+    # This can be devastating for throughput. Increase `output_block_size` to
+    # fix.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow",
+    # Arroyo has decided to re-allocate a block in order to combat input buffer
+    # overflow. This behavior can be disabled by explicitly setting
+    # `input_block_size` to a not-None value in `RunTaskWithMultiprocessing`.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.input.resize",
+    # Arroyo has decided to re-allocate a block in order to combat output buffer
+    # overflow. This behavior can be disabled by explicitly setting
+    # `output_block_size` to a not-None value in `RunTaskWithMultiprocessing`.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.output.resize",
+    # How many batches are being processed in parallel by multiprocessing.
+    "arroyo.strategies.run_task_with_multiprocessing.batches_in_progress",
+    # Counter. A subprocess by multiprocessing unexpectedly died.
+    "sigchld.detected",
+    # Gauge. Shows how many processes the multiprocessing strategy is
+    # configured with.
+    "arroyo.strategies.run_task_with_multiprocessing.processes",
+    # Time (unitless) spent polling librdkafka for new messages.
+    "arroyo.consumer.poll.time",
+    # Time (unitless) spent in strategies (blocking in strategy.submit or
+    # strategy.poll)
+    "arroyo.consumer.processing.time",
+    # Time (unitless) spent pausing the consumer due to backpressure (MessageRejected)
+    "arroyo.consumer.backpressure.time",
+    # Time (unitless) spent in handling `InvalidMessage` exceptions and sending
+    # messages to the the DLQ.
+    "arroyo.consumer.dlq.time",
+    # Time (unitless) spent in waiting for the strategy to exit, such as during
+    # shutdown or rebalancing.
+    "arroyo.consumer.join.time",
+    # Time (unitless) spent in librdkafka callbacks. This metric's timings
+    # overlap other timings, and might spike at the same time.
+    "arroyo.consumer.callback.time",
+    # Time (unitless) spent in shutting down the consumer. This metric's
+    # timings overlap other timings, and might spike at the same time.
+    "arroyo.consumer.shutdown.time",
+    # Queue size of background queue that librdkafka uses to prefetch messages.
+    "arroyo.consumer.librdkafka.total_queue_size",
+    # Counter metric to measure how often the healthcheck file has been touched.
+    "arroyo.processing.strategies.healthcheck.touch",
+    # Number of messages dropped in the FilterStep strategy
+    "arroyo.strategies.filter.dropped_messages",
+]
+
+
+
+
+

API

+
+
+class arroyo.utils.metrics.Metrics(*args, **kwargs)
+

An abstract class that defines the interface for metrics backends.

+
+
+abstract gauge(name: MetricName, value: int | float, tags: Mapping[str, str] | None = None) None
+

Sets a gauge metric to the given value.

+
+ +
+
+abstract increment(name: MetricName, value: int | float = 1, tags: Mapping[str, str] | None = None) None
+

Increments a counter metric by a given value.

+
+ +
+
+abstract timing(name: MetricName, value: int | float, tags: Mapping[str, str] | None = None) None
+

Records a timing metric.

+
+ +
+ +
+
+arroyo.utils.metrics.configure_metrics(metrics: Metrics, force: bool = False) None
+

Metrics can generally only be configured once, unless force is passed +on subsequent initializations.

+
+ +
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..2d626a23faac6c45d982df3e6e6ac062d681adc6 GIT binary patch literal 1299 zcmV+u1?>7GAX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkGa&m8Z zZwezIR%LQ?X>V>iAPOTORA^-&a%F8{X>Md?av*PJAarPHb0B7EY-J#6b0A}HZE$jB zb8}^6Aa!$TZf78RY-wUH3V7PRSkH5uHWa?|S7@d^qzBXH>glwTIOE2Xq}{Qd=D4F3 zZx_Wv!jg!+|9u4#Aa)Tfu-g+Lz3+QJB%bshmQw6RoUmt<@2@kF6b#UB$b73f)fxNA z4qg3>t|HvX#vj=8XPQx6f(XM(p|>99Sa>BECHs@4@AwbQXz~S=!aFD-@Jb-pRPZ6# zC%k>ar6y?%CLmAJ^|uiD6ihA!F?LbDiOMu(O>tIzM|%m{8TCW}s7%Tt>-vLHVV1rlnU{bQHZ zqCsYqoA(PVx;4W>UU-8!B{7j;zSl2Qr|TR`P0Jrf{XZVYDlK#(Ue2-yH&~O@jD?a* zJwGkKG^qFG%Y%kIuq<8r8N7o(<8t=lUt})-SH3xKT!_eOGkez1&aTCFt3a!1D`~Ou zP4)Q4G6ZbyQ!~oHrA*tCvCnclJI!K;xvd@pA@;dPNmIZ~rz8dP6tdM5nP#vL{Mgmg zWA>4nQU2UsKSFl9>1j6CpjFG=V{3eAwQXQP0cek=WC+I%=Sd*dEgT`XYTl8t9-z#Bi*Mf zt!@oj!8C0JM_ug$&2+k#%DMl|%zZgFZ72|7%SKHq_*SqaeNS0V*79JjCEXOJ(wRln)DdUlTC(&W(Rmg>)-(g9ahA{Y?WVcl zPTWKG8VJd%4ah_WuTwM+xqR=|M2lASfMjj5po`5iz6Cp^rub1Oh#5O$<^MGk7pTF; zmDExTVl8q?X0kli*oi(=xR~Q?ZUE)at{khsRp7A z#;j3tod|-i-Xedzl1A?;edf_lL>o+=a%ob>0oot8==a`8RCe5b@umZhKA1~9VxY@L z#B%`!sAvb=ri2o}@CH~3sYfmBu6#9;+8k`MY@U1M?WmRg%dnThtwqZ_vvV$L6*;h{ z<3@08R#jaaDJ?};$_!Yk-?>001u^&|s#m}h^uv$bVn=32_c)mEuj&aWZhr^ss_X3d z+0m?y|} z<)UCqE5O&&_i~|V!f@1f3Q&1HDP(UhQGe?vfIn;wA+Mj*vEpdY^=3-c_Mp*2BM=>T zcmhm*{|C8NQFPSH2!Opt2XY;pH@Bv4`z7irLPH#W3j&!E7nL<`G+fS)a2*!@4Xybj zk?S2qr`E}1x`MTJtF=lc2PJ!SRP6>7d8IJ2HFNZmV!hsq&K9l5tl&5Eg{Z2Nvl;(0 J`VU6C4^6PUdvyQ+ literal 0 HcmV?d00001 diff --git a/offsets.html b/offsets.html new file mode 100644 index 00000000..58aec6c0 --- /dev/null +++ b/offsets.html @@ -0,0 +1,243 @@ + + + + + + Committing offsets - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Committing offsets

+

Arroyo does not auto commit offsets. It is up to you to manually commit offsets when processing for that +message is completed.

+

The commit callback will be passed to processing strategy via ProcessingStrategyFactory.create_with_partitions. +You should pass this to the strategy and have your strategy call this commit function once the rest of the message +processing has been done.

+

The offset to be committed in Kafka is always the next offset to be consumed from, i.e. message’s offset + 1. +In Arroyo, this means you should commit Message.next_offset and never Message.offset when done processing +that message. Arroyo exposes Message.position_to_commit to make this easier.

+

It is not safe to commit every offset in a high throughput consumer as this will add a lot of load to the system. +Commits should generally be throttled. CommitPolicy is the Arroyo way of specifying commit frequency. A CommitPolicy +must be passed to the stream processor, which allows specifying a minimum commit frequency (or messages between commits). +Commit throttling can be skipped when needed (i.e. during consumer shutdown) by passing force=True to the commit callback. +If you are not sure how often to commit, ONCE_PER_SECOND is a reasonable option.

+

The easiest way is to use the CommitOffsets strategy as the last step in a chain of processing strategies to commit offsets.

+
class MyConsumerFactoryFactory(ProcessingStrategyFactory[KafkaPayload]):
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        def my_processing_function(message: Message[KafkaPayload]) -> None:
+            # do something (synchronous) with the message
+            do_something()
+
+
+        return RunTask(my_processing_function, CommitOffsets(commit))
+
+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 00000000..8003e264 --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,210 @@ + + + + + + Python Module Index - Arroyo documentation + + + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+
+ + +

Python Module Index

+ +
+ a +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ a
+ arroyo +
    + arroyo.dlq +
    + arroyo.processing.strategies.abstract +
    + arroyo.processing.strategies.batching +
    + arroyo.processing.strategies.commit +
    + arroyo.processing.strategies.filter +
    + arroyo.processing.strategies.healthcheck +
    + arroyo.processing.strategies.produce +
    + arroyo.processing.strategies.reduce +
    + arroyo.processing.strategies.run_task +
    + arroyo.processing.strategies.run_task_in_threads +
    + arroyo.processing.strategies.run_task_with_multiprocessing +
    + arroyo.processing.strategies.unfold +
    + arroyo.types +
    + arroyo.utils.metrics +
+ + +
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 00000000..a5d5b730 --- /dev/null +++ b/search.html @@ -0,0 +1,154 @@ + + + + + + Search - Arroyo documentation + + + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + +
+

+ + + +
+ +
+ + +
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 00000000..064acf7e --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["architecture", "backpressure", "dlqs", "getstarted", "index", "intro", "metrics", "offsets", "strategies/batching", "strategies/commit_offsets", "strategies/filter", "strategies/healthcheck", "strategies/index", "strategies/produce", "strategies/reduce", "strategies/run_task", "strategies/run_task_in_threads", "strategies/run_task_with_multiprocessing", "strategies/unfold", "what_for"], "filenames": ["architecture.rst", "backpressure.rst", "dlqs.rst", "getstarted.rst", "index.rst", "intro.rst", "metrics.rst", "offsets.rst", "strategies/batching.rst", "strategies/commit_offsets.rst", "strategies/filter.rst", "strategies/healthcheck.rst", "strategies/index.rst", "strategies/produce.rst", "strategies/reduce.rst", "strategies/run_task.rst", "strategies/run_task_in_threads.rst", "strategies/run_task_with_multiprocessing.rst", "strategies/unfold.rst", "what_for.rst"], "titles": ["Arroyo Architecture", "Backpressure", "Dead letter queues", "Getting started with Arroyo", "Contents:", "<no title>", "Metrics", "Committing offsets", "Batch and Unbatch", "Commit offsets", "Filter", "Healthchecks", "Processing Strategies", "Produce", "Reduce (Fold)", "Run Task", "Run Task in Threads", "Run Task with Multiprocessing", "Unfold", "What is Arroyo for?"], "terms": {"i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "set": [0, 2, 4, 5, 6, 11, 17], "abstract": [0, 3, 4, 5, 6, 12, 19], "interact": 0, "kafka": [0, 2, 4, 5, 7, 11, 12, 13], "These": [0, 6], "ar": [0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19], "meant": 0, "help": [0, 19], "develop": 0, "write": [0, 3, 4, 5, 12, 19], "perform": [0, 1, 6, 12, 17, 19], "consum": [0, 1, 2, 4, 5, 6, 7, 10, 11, 12, 13], "specif": 0, "deliveri": 0, "guarante": [0, 2], "common": [0, 4, 5], "problem": 0, "address": 0, "least": [0, 17], "onc": [0, 2, 3, 6, 7, 9, 11, 12, 14, 16, 17, 19], "provid": [0, 2, 3, 4, 5, 8, 12, 15, 18], "dead": [0, 4, 15], "letter": [0, 4, 15], "queue": [0, 4, 6, 15, 19], "support": [0, 2, 11], "parallel": [0, 6, 16, 17], "multi": 0, "process": [0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 18, 19], "messag": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19], "etc": [0, 12], "The": [0, 2, 3, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19], "librari": [0, 3, 4, 5, 19], "divid": [0, 19], "three": [0, 4, 5], "layer": 0, "basic": [0, 10, 15], "connect": 0, "simpl": 0, "wrapper": [0, 3], "around": [0, 3], "confluent": [0, 3], "python": [0, 3, 4, 5, 17], "which": [0, 3, 4, 5, 7, 8, 13, 16, 19], "itself": [0, 4, 5, 13], "base": [0, 1, 8, 12, 14, 18], "librdkafka": [0, 3, 4, 5, 6], "besid": 0, "some": [0, 1, 2, 4, 5, 6, 13, 17], "cosmet": 0, "chang": [0, 3], "thi": [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19], "fake": 0, "memori": [0, 4, 5, 6, 17], "broker": [0, 3, 4, 5, 9, 11, 12, 19], "make": [0, 7, 10, 17, 19], "unit": [0, 4, 5], "test": [0, 3, 4, 5, 11, 17, 19], "quick": 0, "run": [0, 3, 6, 11, 12, 14, 19], "an": [0, 3, 4, 5, 6, 13, 16, 17, 19], "asynchron": [0, 3, 12], "written": [0, 12], "pipelin": [0, 11], "where": [0, 13, 17], "each": [0, 1, 3, 12, 13, 14, 16, 17, 19], "segment": 0, "oper": [0, 19], "implement": [0, 2, 12, 18], "main": [0, 1, 3, 11, 17], "loop": [0, 3, 12], "deleg": 0, "On": [0, 13, 16], "top": [0, 19], "when": [0, 3, 6, 7, 8, 12, 17], "like": [0, 1, 3, 6, 11, 17, 19], "map": [0, 1, 3, 6, 7, 11, 12], "reduc": [0, 6, 8, 12, 17, 19], "filter": [0, 2, 6], "togeth": [0, 8, 12, 14], "applic": [0, 2, 4, 5, 12, 17, 19], "pattern": [0, 4, 5], "A": [0, 1, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 17, 19], "built": [0, 12, 19], "wai": [0, 7, 19], "suppos": [0, 1], "execut": [0, 12], "small": [0, 17], "cpu": [0, 1, 6, 17], "work": [0, 1, 3, 12, 17, 19], "block": [0, 1, 6, 11, 12, 17, 19], "do": [0, 1, 3, 7, 10, 11, 17, 19], "io": [0, 3, 11, 16, 19], "non": 0, "we": [0, 3, 8, 12, 13, 14, 16, 19], "gener": [0, 6, 7, 8, 12, 17, 18], "us": [0, 2, 6, 7, 8, 9, 12, 13, 16, 17, 19], "futur": [0, 13, 16], "heavier": 0, "separ": [0, 19], "call": [0, 3, 7, 8, 11, 12, 18, 19], "processingstrategi": [0, 1, 3, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18], "modul": [0, 17], "todo": [0, 19], "bring": 0, "docstr": 0, "doc": [0, 3, 19], "refer": [0, 13], "In": [0, 2, 3, 6, 7, 17, 19], "most": [0, 1, 3, 6, 11, 12, 17, 19], "case": [0, 13, 17], "would": [0, 8, 11, 19], "directli": 0, "higher": [0, 11, 19], "manag": [0, 3, 4, 5], "phase": 0, "poll": [0, 2, 3, 6, 8, 11, 12, 13, 16, 18, 19], "from": [0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "through": 0, "If": [0, 1, 2, 3, 7, 8, 10, 11, 12, 13, 16, 17, 18, 19], "proce": 0, "repeat": 0, "submit": [0, 1, 2, 3, 6, 8, 10, 12, 13, 14, 16, 18], "first": [0, 3, 8, 14, 17], "deliv": 0, "It": [0, 1, 2, 3, 4, 5, 7, 9, 12], "should": [0, 2, 3, 7, 8, 9, 10, 11, 12, 14, 15, 17, 19], "return": [0, 1, 3, 7, 10, 11, 12, 18, 19], "immedi": [0, 12, 19], "forward": [0, 2, 10, 17], "result": [0, 6, 10, 16, 17], "follow": [0, 8, 12, 14, 17, 19], "step": [0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18], "ideal": 0, "all": [0, 2, 8, 9, 12, 17, 19], "done": [0, 2, 6, 7, 12, 16], "thread": [0, 1, 11, 12, 13], "heavi": 0, "so": [0, 3, 6, 8, 10, 11, 12, 14, 17, 19], "method": [0, 2, 8, 12, 13, 14, 16], "check": [0, 12, 13, 16], "complet": [0, 3, 7, 9, 12, 13, 16], "dispatch": 0, "next": [0, 2, 3, 7, 8, 10, 13, 14, 16, 17, 18, 19], "practic": 0, "here": [0, 3, 17, 19], "overhead": 0, "offload": 0, "too": [0, 1, 11, 13, 16, 17], "mai": [0, 1, 2, 6, 10, 12, 17], "decid": [0, 6, 19], "take": [0, 10, 11, 16, 17], "instead": [0, 8, 10, 17], "appli": [0, 1, 2, 6, 13, 17], "back": [0, 9, 17], "pressur": 0, "rais": [0, 1, 2, 12, 13, 15, 16], "messagereject": [0, 1, 6, 8, 12, 13, 14, 16, 18], "except": [0, 1, 2, 6, 8, 12, 13, 14, 16, 18, 19], "paus": [0, 1, 6], "till": 0, "readi": [0, 3, 8, 14], "accept": [0, 12], "time": [0, 1, 3, 6, 8, 10, 11, 12, 14, 17, 19], "commit": [0, 1, 3, 4, 10, 11, 12], "callback": [0, 1, 6, 7, 10], "instanti": [0, 12], "orchestr": [0, 3], "life": 0, "cycl": 0, "thu": [0, 8], "think": 0, "shut": [0, 6, 11, 12], "down": [0, 1, 6, 11, 12, 13, 16], "wait": [0, 6, 17], "flight": 0, "destroi": [0, 3], "There": [0, 19], "two": [0, 2, 17], "scenario": [0, 2, 10, 19], "can": [0, 1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17], "happen": [0, 11], "being": [0, 2, 6, 12, 13, 19], "termin": [0, 8, 12, 14], "rebalanc": [0, 1, 3, 4, 5, 6, 12], "revok": [0, 3, 12, 19], "partit": [0, 1, 2, 3, 7, 8, 10, 11, 12, 19], "assign": [0, 3, 12, 19], "new": [0, 3, 6, 8, 14, 17, 19], "ones": [0, 12, 17], "after": [0, 3, 6, 9, 11, 12, 19], "imposs": 0, "wa": [0, 6, 8, 12, 13, 17], "order": [0, 2, 3, 6, 8, 14, 17, 19], "ensur": [0, 9], "behav": 0, "consist": [0, 2], "upon": [0, 2], "build": [0, 4, 5, 12, 19], "one": [0, 2, 3, 8, 13, 14, 18, 19], "allow": [0, 7, 8, 12, 14, 19], "befor": [0, 6, 8, 12, 14, 17], "same": [0, 1, 3, 6, 17], "few": [0, 1, 19], "simpler": 0, "exampl": [0, 1, 12, 19], "task": [0, 12], "multiprocess": [0, 6], "design": [0, 19], "flexibl": [0, 12], "thei": [0, 2, 8, 14, 17], "function": [0, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 16, 17, 18], "user": [0, 16, 18, 19], "everi": [0, 2, 3, 7, 10, 19], "pass": [0, 1, 2, 3, 6, 7, 8, 10, 11, 13, 19], "output": [0, 3, 6, 13], "includ": [0, 8], "synchron": [0, 7, 12, 17], "version": 0, "depend": [0, 12], "kind": [0, 11], "concurr": [0, 16], "requir": [0, 1, 2, 3, 8, 19], "type": [0, 3, 6, 10, 12], "inspect": 0, "whether": [0, 8, 14, 19], "discard": [0, 12, 19], "transform": [0, 6, 13, 17], "its": [0, 10, 12, 19], "content": [0, 8], "produc": [0, 2, 3, 4, 5, 12], "topic": [0, 2, 12, 13], "onli": [0, 6, 9, 10, 19], "need": [0, 3, 7, 10, 12, 17, 19], "wire": [0, 12], "them": [0, 8, 10, 17, 18, 19], "logic": [0, 12, 19], "side": 0, "effect": [0, 1, 17], "variat": 0, "abov": [0, 3], "have": [0, 3, 7, 8, 10, 17, 19], "store": [0, 17], "somewher": 0, "throughput": [0, 6, 7, 17], "intens": 0, "gil": 0, "doe": [0, 7, 8, 19], "advantag": 0, "batch": [0, 6, 12, 14], "via": [0, 7], "share": [0, 17], "larg": [0, 17], "transpar": 0, "carri": [0, 10], "out": [0, 8, 11, 17, 19], "collector": 0, "full": [0, 8, 14], "typic": [0, 6, 13], "storag": 0, "round": 0, "trip": 0, "arroyo": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "": [1, 6, 7, 12, 17], "own": [1, 12], "strategi": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18], "intern": [1, 3, 19], "addit": [1, 2, 19], "deal": [1, 10], "correctli": 1, "you": [1, 3, 6, 7, 8, 10, 11, 12, 17, 19], "want": [1, 8, 11, 17, 19], "slow": [1, 12, 13, 16], "extern": [1, 3], "signal": [1, 19], "condit": [1, 14], "achiev": 1, "within": [1, 19], "runtask": [1, 3, 7, 11, 15], "while": [1, 3, 19], "class": [1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "consumerstrategyfactori": [1, 3, 11], "processingstrategyfactori": [1, 3, 7, 11, 12], "kafkapayload": [1, 2, 3, 7, 11], "def": [1, 3, 6, 7, 11, 19], "__init__": [1, 11], "self": [1, 3, 6, 7, 11], "is_paus": [1, 11], "fals": [1, 2, 3, 6, 10, 11, 19], "create_with_partit": [1, 3, 7, 11, 12], "int": [1, 2, 3, 6, 7, 8, 11, 12, 13, 14, 16, 17], "handle_messag": [1, 3, 11], "print": [1, 3], "f": [1, 3], "msg": [1, 3, 6, 17], "payload": [1, 3, 10, 12, 16], "commitoffset": [1, 3, 7, 9, 11], "recommend": [1, 12], "just": [1, 3, 9, 10, 11], "sleep": 1, "ing": 1, "more": [1, 3, 12, 17, 19], "than": [1, 2, 6, 11, 17], "millisecond": [1, 11], "definit": 1, "long": [1, 6, 11], "prevent": [1, 2], "thing": [1, 17, 19], "occur": [1, 13, 16], "0": [1, 3, 19], "01": 1, "second": [1, 3, 6, 8, 11, 14, 17], "spin": [1, 6], "100": [1, 2, 10], "howev": [1, 11, 17, 19], "background": [1, 6], "impact": [1, 19], "dure": [1, 6, 7, 12], "caution": 2, "break": [2, 17], "otherwis": [2, 19], "offer": 2, "code": [2, 3, 11, 12, 19], "particular": 2, "must": [2, 6, 7, 18], "safe": [2, 7], "drop": [2, 6, 10], "replai": 2, "later": [2, 10, 12], "re": [2, 6, 17, 19], "dlq": [2, 6], "ed": 2, "critic": 2, "relev": 2, "downstream": [2, 8, 10, 14], "rout": 2, "invalid": [2, 6, 15], "becaus": [2, 6, 10, 11, 17], "singl": [2, 12, 13, 18], "caus": [2, 10, 17], "crash": [2, 12], "subsequ": [2, 6, 18], "configur": [2, 3, 6, 17], "streamprocessor": [2, 3, 12], "ani": [2, 12, 17, 19], "invalidmessag": [2, 6, 15], "dlqlimit": 2, "max_invalid_ratio": 2, "float": [2, 6, 8, 12, 14, 17], "none": [2, 3, 6, 7, 8, 10, 12, 14, 17], "max_consecutive_count": 2, "defin": [2, 6, 12], "limit": [2, 17], "place": 2, "number": [2, 6, 8, 12, 19], "exist": 2, "go": 2, "someth": [2, 7, 12, 19], "misconfigur": 2, "bad": [2, 19], "deploi": [2, 19], "prefer": 2, "stop": 2, "altogeth": 2, "fix": [2, 6, 17, 19], "rather": [2, 10, 17], "rerout": 2, "ratio": 2, "count": [2, 6], "per": [2, 6, 8, 11, 17, 19], "basi": 2, "dlqpolici": 2, "dlqproduc": 2, "tstrategypayload": [2, 8, 10, 11, 12, 13, 15, 16, 17], "max_buffered_messages_per_partit": 2, "polici": 2, "stream": [2, 4, 5, 7, 10, 12, 13, 16], "processor": [2, 3, 7, 12, 13, 16], "creation": 2, "offset": [2, 3, 4, 5, 8, 10, 12, 17, 19], "needs_commit": 2, "bool": [2, 6, 10], "true": [2, 3, 7, 19], "valid": 2, "retri": [2, 12], "join": [2, 6, 8, 12, 14], "multipl": [2, 11, 19], "kafkadlqproduc": 2, "field": 2, "ad": [2, 8, 14], "header": [2, 3], "original_partit": 2, "origin": [2, 13, 16], "original_offset": 2, "noopdlqproduc": 2, "arg": [2, 6, 11, 12], "kwd": [2, 12], "tutori": 3, "show": [3, 6, 17], "how": [3, 6, 7, 8, 12, 14], "scratch": 3, "section": [3, 17, 19], "explain": [3, 19], "alreadi": [3, 19], "skip": [3, 7], "command": [3, 11], "docker": 3, "contain": [3, 10, 11, 12, 16], "network": [3, 19], "rm": [3, 11], "v": 3, "zookeeper_volum": 3, "var": 3, "lib": 3, "env": 3, "zookeeper_client_port": 3, "2181": 3, "name": [3, 6, 11, 12], "sentry_zookeep": 3, "p": 3, "confluentinc": 3, "cp": 3, "6": 3, "2": 3, "kafka_volum": 3, "kafka_zookeeper_connect": 3, "kafka_listen": 3, "9093": 3, "9092": [3, 19], "kafka_advertised_listen": 3, "127": 3, "1": [3, 6, 7, 12], "kafka_listener_security_protocol_map": 3, "plaintext": 3, "kafka_inter_broker_listener_nam": 3, "kafka_offsets_topic_replication_factor": 3, "confluent_support_metrics_en": 3, "kafka_log4j_logg": 3, "cluster": 3, "warn": 3, "control": [3, 19], "coordin": 3, "log": [3, 19], "server": [3, 19], "state": [3, 17, 19], "logger": 3, "kafka_log4j_root_loglevel": 3, "kafka_tools_log4j_loglevel": 3, "sentry_kafka": 3, "now": [3, 17, 19], "see": [3, 17, 19], "tool": 3, "onto": 3, "http": [3, 19], "platform": 3, "current": [3, 8, 14, 19], "app": 3, "usag": 3, "html": 3, "kcat": 3, "formerli": 3, "util": [3, 6], "venv": 3, "virtual": 3, "Then": [3, 17], "pip": 3, "sentri": 3, "our": [3, 19], "anoth": [3, 13], "exec": [3, 11], "sourc": 3, "bootstrap": [3, 19], "dest": 3, "level": [3, 11, 19], "thin": 3, "featur": [3, 17], "interfac": [3, 6], "hide": 3, "detail": 3, "lifecycl": 3, "initi": [3, 6, 17], "backend": [3, 6, 11], "import": [3, 6, 13, 19], "build_kafka_consumer_configur": 3, "kafkaconsum": [3, 11], "default_config": 3, "bootstrap_serv": 3, "auto_offset_reset": 3, "latest": [3, 19], "group_id": 3, "group": [3, 12], "subscrib": [3, 19], "timeout": [3, 8, 12, 14, 19], "script": 3, "echo": 3, "b": 3, "t": [3, 10, 12, 17], "appear": 3, "consol": 3, "kei": 3, "valu": [3, 6, 12, 14, 17, 19], "custom": [3, 8, 12, 14, 15, 18, 19], "over": [3, 12], "factori": 3, "close": [3, 8, 12, 17], "runtim": 3, "processor_factori": 3, "period": [3, 6, 10, 19], "consumerstrategi": 3, "invers": 3, "chain": [3, 7, 9], "kafkaproduc": 3, "build_kafka_configur": 3, "simpli": 3, "find": [3, 6], "reli": [4, 5], "confluent_kafka": [4, 5, 19], "mainli": [4, 5], "inspir": [4, 5], "simplifi": [4, 5], "what": [4, 10, 17], "get": [4, 17, 19], "start": [4, 11, 17], "architectur": [4, 19], "backpressur": [4, 6, 17, 19], "metric": [4, 17], "attempt": [6, 8, 13, 18, 19], "auto": [6, 7, 19], "instrument": 6, "peopl": 6, "understand": [6, 19], "behavior": [6, 10, 19], "sampl": 6, "buffer": [6, 19], "appropri": 6, "flush": [6, 8, 14, 19], "often": [6, 7, 19], "conform": 6, "protocol": 6, "creat": [6, 8, 14, 18], "your": [6, 7, 10, 11, 12, 19], "metricnam": 6, "mymetr": 6, "increment": [6, 17], "union": [6, 10], "tag": 6, "option": [6, 7, 11], "counter": 6, "given": [6, 17], "record_incr": 6, "gaug": 6, "record_gaug": 6, "emit": [6, 10, 17], "record_tim": 6, "metrics_backend": 6, "configure_metr": 6, "liter": 6, "run_task_with_multiprocess": [6, 17], "size": [6, 14, 17, 18], "byte": [6, 17], "output_batch": 6, "encount": [6, 17], "invalid_messag": 6, "took": 6, "fill": [6, 17], "up": [6, 7, 12, 17, 19], "batch_tim": 6, "reason": [6, 7, 10], "why": 6, "cannot": [6, 10, 19], "satur": 6, "input": 6, "enough": 6, "alloc": [6, 17], "smaller": [6, 17], "increas": [6, 17], "input_block_s": [6, 17], "overflow": [6, 17], "pull": 6, "equal": 6, "devast": 6, "output_block_s": [6, 17], "ha": [6, 7, 8, 11, 12, 13, 19], "combat": 6, "disabl": 6, "explicitli": [6, 17], "runtaskwithmultiprocess": [6, 17], "resiz": [6, 17], "mani": [6, 8, 10, 11, 12, 13, 14, 16, 17, 19], "batches_in_progress": [6, 17], "subprocess": [6, 17], "unexpectedli": 6, "di": [6, 19], "sigchld": 6, "detect": 6, "unitless": 6, "spent": [6, 8, 14, 17], "due": [6, 12, 19], "handl": [6, 10, 19], "send": [6, 8, 17, 19], "exit": [6, 12], "shutdown": [6, 7, 12], "overlap": 6, "other": [6, 10, 12], "might": [6, 17], "spike": 6, "prefetch": 6, "total_queue_s": 6, "measur": 6, "healthcheck": 6, "file": [6, 11, 12, 19], "been": [6, 7, 8, 12, 13, 19], "touch": [6, 11], "filterstep": [6, 10], "dropped_messag": 6, "kwarg": [6, 12], "str": [6, 11, 12], "record": 6, "forc": [6, 7], "unless": 6, "manual": [7, 19], "rest": 7, "alwai": [7, 9, 13], "e": [7, 10, 18], "mean": [7, 17, 19], "next_offset": [7, 12], "never": [7, 17], "expos": 7, "position_to_commit": 7, "easier": 7, "high": [7, 8], "add": [7, 19], "lot": [7, 17, 19], "load": [7, 17], "system": [7, 10], "throttl": 7, "commitpolici": [7, 10], "specifi": [7, 16], "frequenc": 7, "minimum": 7, "between": [7, 17], "sure": [7, 19], "once_per_second": 7, "easiest": 7, "last": [7, 9], "myconsumerfactoryfactori": 7, "my_processing_funct": 7, "do_someth": 7, "accumul": [8, 14], "unfold": 8, "batchstep": 8, "max_batch_s": [8, 14, 17], "max_batch_tim": [8, 14, 17], "next_step": [8, 10, 11, 13, 14, 15, 16, 17, 18], "mutablesequ": 8, "basevalu": [8, 12, 14], "repres": [8, 12], "valuesbatch": 8, "object": [8, 16], "sequenc": [8, 18], "both": 8, "watermark": 8, "maximum": [8, 14], "receiv": [8, 12, 13, 14, 16, 18], "sinc": [8, 12, 16, 17], "sent": 8, "though": 8, "highest": [8, 17], "observ": [8, 17], "still": [8, 17], "committ": [8, 12], "lower": 8, "propag": [8, 14], "thrown": [8, 12, 14], "paramet": [8, 12, 14, 17], "much": [8, 14, 19], "tri": [8, 14], "matter": [8, 14], "filteredpayload": [8, 10, 12, 13, 14, 15, 16, 17, 18], "without": [8, 14, 17, 19], "previou": [8, 12, 14, 17, 19], "try": [8, 14], "again": [8, 14, 17, 19], "introduc": [8, 14], "duplic": [8, 14], "unbatchstep": 8, "explod": [8, 18], "keep": [8, 11, 12, 17, 18], "remain": [8, 18], "prior": [9, 12], "callabl": [10, 14, 15, 16, 17, 18], "commit_polici": 10, "determin": 10, "sometim": 10, "actual": [10, 19], "desir": 10, "regular": 10, "interv": [10, 11, 12], "For": [10, 13, 16, 17], "That": [10, 17], "sentinel": 10, "those": [10, 17], "abl": [10, 17], "subtyp": 10, "doesn": [10, 17], "compos": 10, "default": [10, 11, 19], "despit": 10, "tell": [10, 11, 12], "turn": 11, "unhealthi": 11, "max": [11, 14], "m": [11, 19], "kick": [11, 19], "300000": 11, "5": 11, "minut": 11, "noth": 11, "pod": [11, 19], "well": 11, "repeatedli": 11, "indic": [11, 15], "health": 11, "tmp": 11, "txt": 11, "kubernet": 11, "live": 11, "look": [11, 17, 19], "apivers": 11, "v1": 11, "metadata": 11, "label": 11, "spec": 11, "imag": 11, "registri": 11, "k8": 11, "busybox": 11, "bin": 11, "my_arroyo_consum": 11, "livenessprob": 11, "initialdelaysecond": 11, "periodsecond": 11, "320": 11, "healthcheck_fil": 11, "filepath": 11, "everytim": 11, "overal": 11, "debounc": 11, "compon": 12, "normal": [12, 17], "don": [12, 17, 19], "encourag": 12, "plug": 12, "nevertheless": 12, "against": 12, "unabl": 12, "rate": [12, 17], "incom": 12, "abc": 12, "cours": 12, "intention": 12, "prescript": 12, "afford": 12, "signific": 12, "degre": 12, "variou": 12, "instanc": 12, "No": [12, 19], "finish": 12, "were": [12, 17], "releas": 12, "resourc": 12, "longer": 12, "socket": 12, "until": [12, 14, 19], "previous": 12, "reach": [12, 19], "grace": 12, "revoc": [12, 19], "progress": 12, "continu": [12, 17], "statu": 12, "schedul": [12, 19], "iter": [12, 18], "amount": 12, "exce": 12, "caller": 12, "assum": 12, "successfulli": [12, 13], "impli": 12, "capac": [12, 17], "abandon": 12, "wrap": 12, "seri": 12, "recreat": 12, "recent": 12, "entir": [12, 17, 19], "note": [12, 17], "also": [12, 17, 19], "properti": 12, "tmessagepayload": 12, "replac": 12, "treplac": 12, "brokervalu": 12, "timestamp": 12, "datetim": 12, "present": 12, "either": 12, "els": 12, "payload_unfilt": 12, "index": 12, "span": 12, "max_buffer_s": 13, "10000": 13, "destin": [13, 19], "could": [13, 19], "pend": [13, 16], "notifi": [13, 16], "error": [13, 16, 19], "constructor": 13, "referenc": 13, "tresult": [14, 15, 16, 17], "tpayload": 14, "initial_valu": 14, "hit": [14, 17], "run_task": 15, "put": 15, "run_task_in_thread": 16, "runtaskinthread": 16, "processing_funct": 16, "max_pending_futur": 16, "bound": 16, "avoid": [16, 17], "modifi": 16, "differ": [16, 19], "protect": 16, "lock": [16, 17], "num_process": 17, "max_input_block_s": 17, "max_output_block_s": 17, "across": 17, "stdlib": 17, "spawn": 17, "message_s": 17, "expect": 17, "averag": 17, "implicitli": 17, "broken": 17, "automat": 17, "adjust": 17, "adapt": 17, "traffic": 17, "mind": [17, 19], "experiment": 17, "less": 17, "production": 17, "data": 17, "enabl": [17, 19], "upper": 17, "begin": 17, "parent": 17, "interpret": 17, "django": 17, "point": 17, "line": [17, 19], "bottleneck": 17, "good": [17, 19], "reserv": 17, "But": 17, "faster": [17, 19], "tweak": 17, "optim": 17, "cost": 17, "amort": 17, "spend": 17, "flat": 17, "perfectli": 17, "straight": 17, "constant": 17, "neither": 17, "ey": 17, "ran": 17, "respons": 17, "realli": 17, "expens": [17, 19], "affect": 17, "confus": 17, "best": 17, "anywai": 17, "fetch": 17, "chunk": 17, "veri": [17, 19], "won": [17, 19], "notic": 17, "regress": 17, "sens": 17, "rid": 17, "issu": [17, 19], "backlog": 17, "lag": 17, "remov": [17, 19], "potenti": 17, "tinput": 18, "collect": 18, "toutput": 18, "accord": 18, "testabl": 19, "document": 19, "outlin": 19, "intricaci": 19, "easi": 19, "awai": 19, "worri": 19, "about": 19, "possibl": 19, "reproduc": 19, "environ": 19, "visual": 19, "event": 19, "driven": 19, "view": 19, "push": 19, "diagram": 19, "below": 19, "accur": 19, "model": 19, "persist": 19, "read": 19, "conf": 19, "localhost": 19, "id": 19, "my_group": 19, "reset": 19, "my_top": 19, "send_to_destin": 19, "process_messag": 19, "satisfi": 19, "mention": 19, "page": 19, "subsect": 19, "By": 19, "To": 19, "lead": 19, "throw": 19, "lost": 19, "know": 19, "config": 19, "u": 19, "sever": 19, "hurt": 19, "replic": 19, "inform": 19, "And": 19, "pure": 19, "descript": 19, "append": 19, "len": 19, "batch_siz": 19, "hand": 19, "wave": 19, "sai": 19, "destination_top": 19, "At": 19, "ever": 19, "transmiss": 19, "delivery_callback": 19, "on_deliveri": 19, "n": 19, "exactli": 19, "rebal": 19, "off": 19, "whenev": 19, "idea": 19, "annoi": 19, "imagin": 19, "decis": 19, "made": 19, "let": 19, "pick": 19, "on_revok": 19, "flush_current_batch": 19, "core": 19, "mechan": 19, "flow": 19, "clear": 19, "possibli": 19, "invok": 19, "respect": 19, "gotcha": 19, "kept": 19, "comit": 19, "api": 19, "www": 19, "educba": 19, "com": 19}, "objects": {"arroyo": [[2, 0, 0, "-", "dlq"], [12, 0, 0, "-", "types"]], "arroyo.dlq": [[2, 1, 1, "", "DlqLimit"], [2, 1, 1, "", "DlqPolicy"], [2, 2, 1, "", "InvalidMessage"], [2, 1, 1, "", "KafkaDlqProducer"], [2, 1, 1, "", "NoopDlqProducer"]], "arroyo.processing.strategies": [[12, 0, 0, "-", "abstract"], [8, 0, 0, "-", "batching"], [9, 0, 0, "-", "commit"], [10, 0, 0, "-", "filter"], [11, 0, 0, "-", "healthcheck"], [13, 0, 0, "-", "produce"], [14, 0, 0, "-", "reduce"], [15, 0, 0, "-", "run_task"], [16, 0, 0, "-", "run_task_in_threads"], [17, 0, 0, "-", "run_task_with_multiprocessing"], [18, 0, 0, "-", "unfold"]], "arroyo.processing.strategies.abstract": [[12, 2, 1, "", "MessageRejected"], [12, 1, 1, "", "ProcessingStrategy"], [12, 1, 1, "", "ProcessingStrategyFactory"]], "arroyo.processing.strategies.abstract.ProcessingStrategy": [[12, 3, 1, "", "close"], [12, 3, 1, "", "join"], [12, 3, 1, "", "poll"], [12, 3, 1, "", "submit"], [12, 3, 1, "", "terminate"]], "arroyo.processing.strategies.abstract.ProcessingStrategyFactory": [[12, 3, 1, "", "create_with_partitions"], [12, 3, 1, "", "shutdown"]], "arroyo.processing.strategies.batching": [[8, 1, 1, "", "BatchStep"], [8, 1, 1, "", "UnbatchStep"]], "arroyo.processing.strategies.batching.BatchStep": [[8, 3, 1, "", "join"], [8, 3, 1, "", "submit"]], "arroyo.processing.strategies.commit": [[9, 1, 1, "", "CommitOffsets"]], "arroyo.processing.strategies.filter": [[10, 1, 1, "", "FilterStep"]], "arroyo.processing.strategies.healthcheck": [[11, 1, 1, "", "Healthcheck"]], "arroyo.processing.strategies.produce": [[13, 1, 1, "", "Produce"]], "arroyo.processing.strategies.reduce": [[14, 1, 1, "", "Reduce"]], "arroyo.processing.strategies.reduce.Reduce": [[14, 3, 1, "", "join"], [14, 3, 1, "", "submit"]], "arroyo.processing.strategies.run_task": [[15, 1, 1, "", "RunTask"]], "arroyo.processing.strategies.run_task_in_threads": [[16, 1, 1, "", "RunTaskInThreads"]], "arroyo.processing.strategies.run_task_with_multiprocessing": [[17, 1, 1, "", "RunTaskWithMultiprocessing"]], "arroyo.processing.strategies.unfold": [[18, 1, 1, "", "Unfold"]], "arroyo.types": [[12, 1, 1, "", "BaseValue"], [12, 1, 1, "", "BrokerValue"], [12, 1, 1, "", "Commit"], [12, 1, 1, "", "FilteredPayload"], [12, 1, 1, "", "Message"], [12, 1, 1, "", "Partition"], [12, 1, 1, "", "Topic"], [12, 1, 1, "", "Value"]], "arroyo.types.BaseValue": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "payload"], [12, 3, 1, "", "replace"]], "arroyo.types.BrokerValue": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "next_offset"], [12, 5, 1, "", "offset"], [12, 5, 1, "", "partition"], [12, 4, 1, "", "payload"], [12, 3, 1, "", "replace"], [12, 5, 1, "", "timestamp"]], "arroyo.types.Message": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "payload"], [12, 4, 1, "", "payload_unfiltered"], [12, 3, 1, "", "replace"], [12, 5, 1, "", "value"]], "arroyo.types.Partition": [[12, 5, 1, "", "index"], [12, 5, 1, "", "topic"]], "arroyo.types.Topic": [[12, 5, 1, "", "name"]], "arroyo.types.Value": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "payload"], [12, 3, 1, "", "replace"]], "arroyo.utils": [[6, 0, 0, "-", "metrics"]], "arroyo.utils.metrics": [[6, 1, 1, "", "Metrics"], [6, 6, 1, "", "configure_metrics"]], "arroyo.utils.metrics.Metrics": [[6, 3, 1, "", "gauge"], [6, 3, 1, "", "increment"], [6, 3, 1, "", "timing"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:exception", "3": "py:method", "4": "py:property", "5": "py:attribute", "6": "py:function"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "exception", "Python exception"], "3": ["py", "method", "Python method"], "4": ["py", "property", "Python property"], "5": ["py", "attribute", "Python attribute"], "6": ["py", "function", "Python function"]}, "titleterms": {"arroyo": [0, 3, 19], "architectur": 0, "stream": [0, 3], "interfac": [0, 12], "engin": 0, "high": [0, 19], "level": 0, "strategi": [0, 12], "backpressur": 1, "dead": 2, "letter": 2, "queue": 2, "get": 3, "start": 3, "setup": 3, "kafka": [3, 19], "zookeep": 3, "instal": 3, "kafkacat": 3, "develop": 3, "environ": 3, "creat": 3, "two": 3, "topic": [3, 19], "basic": 3, "consum": [3, 17, 19], "add": 3, "some": 3, "us": 3, "logic": 3, "further": 3, "exampl": 3, "content": 4, "metric": 6, "avail": 6, "api": 6, "commit": [7, 9, 19], "offset": [7, 9], "batch": [8, 17, 19], "unbatch": 8, "filter": 10, "healthcheck": 11, "process": [12, 17], "messag": 12, "produc": [13, 19], "reduc": 14, "fold": 14, "run": [15, 16, 17], "task": [15, 16, 17], "thread": 16, "multiprocess": 17, "number": 17, "input": 17, "output": 17, "buffer": 17, "how": [17, 19], "tune": 17, "your": 17, "unfold": 18, "what": 19, "i": 19, "goal": 19, "why": 19, "simpl": 19, "doesn": 19, "t": 19, "cut": 19, "It": 19, "provid": 19, "deliveri": 19, "guarante": 19, "throughput": 19, "reliabl": 19, "deal": 19, "With": 19, "rebalanc": 19, "when": 19, "can": 19, "happen": 19, "affect": 19, "librdkafka": 19, "": 19, "callback": 19, "hell": 19, "conclus": 19, "appendix": 19, "group": 19}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx": 58}, "alltitles": {"Arroyo Architecture": [[0, "arroyo-architecture"]], "Streaming Interface and Streaming Engine": [[0, "streaming-interface-and-streaming-engine"]], "High level strategies": [[0, "high-level-strategies"]], "Backpressure": [[1, "backpressure"]], "Dead letter queues": [[2, "dead-letter-queues"]], "Getting started with Arroyo": [[3, "getting-started-with-arroyo"]], "Setup": [[3, "setup"]], "Kafka and Zookeeper": [[3, "kafka-and-zookeeper"]], "Install Kafkacat": [[3, "install-kafkacat"]], "Development environment": [[3, "development-environment"]], "Create two Kafka topics": [[3, "create-two-kafka-topics"]], "Create a basic consumer": [[3, "create-a-basic-consumer"]], "Creating a basic consumer": [[3, "creating-a-basic-consumer"]], "Create a streaming consumer": [[3, "create-a-streaming-consumer"]], "Add some useful logic": [[3, "add-some-useful-logic"]], "Further examples": [[3, "further-examples"]], "Contents:": [[4, "contents"]], "Metrics": [[6, "metrics"]], "Available Metrics": [[6, "available-metrics"]], "API": [[6, "module-arroyo.utils.metrics"]], "Committing offsets": [[7, "committing-offsets"]], "Batch and Unbatch": [[8, "batch-and-unbatch"]], "Commit offsets": [[9, "commit-offsets"]], "Filter": [[10, "module-arroyo.processing.strategies.filter"]], "Healthchecks": [[11, "healthchecks"]], "Processing Strategies": [[12, "processing-strategies"]], "Strategy interface": [[12, "strategy-interface"]], "Messages": [[12, "module-arroyo.types"]], "Produce": [[13, "module-arroyo.processing.strategies.produce"]], "Reduce (Fold)": [[14, "reduce-fold"]], "Run Task": [[15, "module-arroyo.processing.strategies.run_task"]], "Run Task in Threads": [[16, "module-arroyo.processing.strategies.run_task_in_threads"]], "Run Task with Multiprocessing": [[17, "module-arroyo.processing.strategies.run_task_with_multiprocessing"]], "Number of processes": [[17, "number-of-processes"]], "Batching": [[17, "batching"]], "Input and output buffers": [[17, "input-and-output-buffers"]], "How to tune your consumer": [[17, "how-to-tune-your-consumer"]], "Unfold": [[18, "unfold"]], "What is Arroyo for?": [[19, "what-is-arroyo-for"]], "Goals": [[19, "goals"]], "Why Simple Doesn\u2019t Cut It": [[19, "why-simple-doesnt-cut-it"]], "Providing delivery guarantees": [[19, "providing-delivery-guarantees"]], "High Throughput": [[19, "high-throughput"]], "Reliable High Throughput Batched Producers": [[19, "reliable-high-throughput-batched-producers"]], "Dealing With Rebalancing": [[19, "dealing-with-rebalancing"]], "What is Rebalancing": [[19, "what-is-rebalancing"]], "When Rebalancing Can Happen": [[19, "when-rebalancing-can-happen"]], "How Rebalancing Affects a Consumer": [[19, "how-rebalancing-affects-a-consumer"]], "librdkafka\u2019s Callback Hell": [[19, "librdkafkas-callback-hell"]], "Conclusion": [[19, "conclusion"]], "Appendix": [[19, "appendix"]], "Committing to a Kafka Topic": [[19, "committing-to-a-kafka-topic"]], "What is a Kafka Consumer Group": [[19, "what-is-a-kafka-consumer-group"]]}, "indexentries": {"dlqlimit (class in arroyo.dlq)": [[2, "arroyo.dlq.DlqLimit"]], "dlqpolicy (class in arroyo.dlq)": [[2, "arroyo.dlq.DlqPolicy"]], "invalidmessage": [[2, "arroyo.dlq.InvalidMessage"]], "kafkadlqproducer (class in arroyo.dlq)": [[2, "arroyo.dlq.KafkaDlqProducer"]], "noopdlqproducer (class in arroyo.dlq)": [[2, "arroyo.dlq.NoopDlqProducer"]], "arroyo.dlq": [[2, "module-arroyo.dlq"]], "module": [[2, "module-arroyo.dlq"], [6, "module-arroyo.utils.metrics"], [8, "module-arroyo.processing.strategies.batching"], [9, "module-arroyo.processing.strategies.commit"], [10, "module-arroyo.processing.strategies.filter"], [11, "module-arroyo.processing.strategies.healthcheck"], [12, "module-arroyo.processing.strategies.abstract"], [12, "module-arroyo.types"], [13, "module-arroyo.processing.strategies.produce"], [14, "module-arroyo.processing.strategies.reduce"], [15, "module-arroyo.processing.strategies.run_task"], [16, "module-arroyo.processing.strategies.run_task_in_threads"], [17, "module-arroyo.processing.strategies.run_task_with_multiprocessing"], [18, "module-arroyo.processing.strategies.unfold"]], "metrics (class in arroyo.utils.metrics)": [[6, "arroyo.utils.metrics.Metrics"]], "arroyo.utils.metrics": [[6, "module-arroyo.utils.metrics"]], "configure_metrics() (in module arroyo.utils.metrics)": [[6, "arroyo.utils.metrics.configure_metrics"]], "gauge() (arroyo.utils.metrics.metrics method)": [[6, "arroyo.utils.metrics.Metrics.gauge"]], "increment() (arroyo.utils.metrics.metrics method)": [[6, "arroyo.utils.metrics.Metrics.increment"]], "timing() (arroyo.utils.metrics.metrics method)": [[6, "arroyo.utils.metrics.Metrics.timing"]], "batchstep (class in arroyo.processing.strategies.batching)": [[8, "arroyo.processing.strategies.batching.BatchStep"]], "unbatchstep (class in arroyo.processing.strategies.batching)": [[8, "arroyo.processing.strategies.batching.UnbatchStep"]], "arroyo.processing.strategies.batching": [[8, "module-arroyo.processing.strategies.batching"]], "join() (arroyo.processing.strategies.batching.batchstep method)": [[8, "arroyo.processing.strategies.batching.BatchStep.join"]], "submit() (arroyo.processing.strategies.batching.batchstep method)": [[8, "arroyo.processing.strategies.batching.BatchStep.submit"]], "commitoffsets (class in arroyo.processing.strategies.commit)": [[9, "arroyo.processing.strategies.commit.CommitOffsets"]], "arroyo.processing.strategies.commit": [[9, "module-arroyo.processing.strategies.commit"]], "filterstep (class in arroyo.processing.strategies.filter)": [[10, "arroyo.processing.strategies.filter.FilterStep"]], "arroyo.processing.strategies.filter": [[10, "module-arroyo.processing.strategies.filter"]], "healthcheck (class in arroyo.processing.strategies.healthcheck)": [[11, "arroyo.processing.strategies.healthcheck.Healthcheck"]], "arroyo.processing.strategies.healthcheck": [[11, "module-arroyo.processing.strategies.healthcheck"]], "basevalue (class in arroyo.types)": [[12, "arroyo.types.BaseValue"]], "brokervalue (class in arroyo.types)": [[12, "arroyo.types.BrokerValue"]], "commit (class in arroyo.types)": [[12, "arroyo.types.Commit"]], "filteredpayload (class in arroyo.types)": [[12, "arroyo.types.FilteredPayload"]], "message (class in arroyo.types)": [[12, "arroyo.types.Message"]], "messagerejected": [[12, "arroyo.processing.strategies.abstract.MessageRejected"]], "partition (class in arroyo.types)": [[12, "arroyo.types.Partition"]], "processingstrategy (class in arroyo.processing.strategies.abstract)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy"]], "processingstrategyfactory (class in arroyo.processing.strategies.abstract)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategyFactory"]], "topic (class in arroyo.types)": [[12, "arroyo.types.Topic"]], "value (class in arroyo.types)": [[12, "arroyo.types.Value"]], "arroyo.processing.strategies.abstract": [[12, "module-arroyo.processing.strategies.abstract"]], "arroyo.types": [[12, "module-arroyo.types"]], "close() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.close"]], "committable (arroyo.types.basevalue property)": [[12, "arroyo.types.BaseValue.committable"]], "committable (arroyo.types.brokervalue property)": [[12, "arroyo.types.BrokerValue.committable"]], "committable (arroyo.types.message property)": [[12, "arroyo.types.Message.committable"]], "committable (arroyo.types.value property)": [[12, "arroyo.types.Value.committable"]], "create_with_partitions() (arroyo.processing.strategies.abstract.processingstrategyfactory method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategyFactory.create_with_partitions"]], "index (arroyo.types.partition attribute)": [[12, "arroyo.types.Partition.index"]], "join() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.join"]], "name (arroyo.types.topic attribute)": [[12, "arroyo.types.Topic.name"]], "next_offset (arroyo.types.brokervalue property)": [[12, "arroyo.types.BrokerValue.next_offset"]], "offset (arroyo.types.brokervalue attribute)": [[12, "arroyo.types.BrokerValue.offset"]], "partition (arroyo.types.brokervalue attribute)": [[12, "arroyo.types.BrokerValue.partition"]], "payload (arroyo.types.basevalue property)": [[12, "arroyo.types.BaseValue.payload"]], "payload (arroyo.types.brokervalue property)": [[12, "arroyo.types.BrokerValue.payload"]], "payload (arroyo.types.message property)": [[12, "arroyo.types.Message.payload"]], "payload (arroyo.types.value property)": [[12, "arroyo.types.Value.payload"]], "payload_unfiltered (arroyo.types.message property)": [[12, "arroyo.types.Message.payload_unfiltered"]], "poll() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.poll"]], "replace() (arroyo.types.basevalue method)": [[12, "arroyo.types.BaseValue.replace"]], "replace() (arroyo.types.brokervalue method)": [[12, "arroyo.types.BrokerValue.replace"]], "replace() (arroyo.types.message method)": [[12, "arroyo.types.Message.replace"]], "replace() (arroyo.types.value method)": [[12, "arroyo.types.Value.replace"]], "shutdown() (arroyo.processing.strategies.abstract.processingstrategyfactory method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategyFactory.shutdown"]], "submit() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.submit"]], "terminate() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.terminate"]], "timestamp (arroyo.types.brokervalue attribute)": [[12, "arroyo.types.BrokerValue.timestamp"]], "topic (arroyo.types.partition attribute)": [[12, "arroyo.types.Partition.topic"]], "value (arroyo.types.message attribute)": [[12, "arroyo.types.Message.value"]], "produce (class in arroyo.processing.strategies.produce)": [[13, "arroyo.processing.strategies.produce.Produce"]], "arroyo.processing.strategies.produce": [[13, "module-arroyo.processing.strategies.produce"]], "reduce (class in arroyo.processing.strategies.reduce)": [[14, "arroyo.processing.strategies.reduce.Reduce"]], "arroyo.processing.strategies.reduce": [[14, "module-arroyo.processing.strategies.reduce"]], "join() (arroyo.processing.strategies.reduce.reduce method)": [[14, "arroyo.processing.strategies.reduce.Reduce.join"]], "submit() (arroyo.processing.strategies.reduce.reduce method)": [[14, "arroyo.processing.strategies.reduce.Reduce.submit"]], "runtask (class in arroyo.processing.strategies.run_task)": [[15, "arroyo.processing.strategies.run_task.RunTask"]], "arroyo.processing.strategies.run_task": [[15, "module-arroyo.processing.strategies.run_task"]], "runtaskinthreads (class in arroyo.processing.strategies.run_task_in_threads)": [[16, "arroyo.processing.strategies.run_task_in_threads.RunTaskInThreads"]], "arroyo.processing.strategies.run_task_in_threads": [[16, "module-arroyo.processing.strategies.run_task_in_threads"]], "runtaskwithmultiprocessing (class in arroyo.processing.strategies.run_task_with_multiprocessing)": [[17, "arroyo.processing.strategies.run_task_with_multiprocessing.RunTaskWithMultiprocessing"]], "arroyo.processing.strategies.run_task_with_multiprocessing": [[17, "module-arroyo.processing.strategies.run_task_with_multiprocessing"]], "unfold (class in arroyo.processing.strategies.unfold)": [[18, "arroyo.processing.strategies.unfold.Unfold"]], "arroyo.processing.strategies.unfold": [[18, "module-arroyo.processing.strategies.unfold"]]}}) \ No newline at end of file diff --git a/strategies/batching.html b/strategies/batching.html new file mode 100644 index 00000000..630b35e6 --- /dev/null +++ b/strategies/batching.html @@ -0,0 +1,293 @@ + + + + + + Batch and Unbatch - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Batch and Unbatch

+

Accumulate messages into a batch and pass to the next step. +The batch and unbatch strategies are based on reduce and unfold. +Use reduce/unfold instead if you want to provide custom +accumulator/generator functions.

+
+
+class arroyo.processing.strategies.batching.BatchStep(max_batch_size: int, max_batch_time: float, next_step: ProcessingStrategy[MutableSequence[BaseValue[TStrategyPayload]]])
+

Accumulates messages into a batch. When the batch is full, this +strategy submits it to the next step.

+

A batch is represented as a ValuesBatch object which is a sequence +of BaseValue. This includes both the messages and the high offset +watermark.

+

A messages batch is closed and submitted when the maximum number of +messages is received or when the max_batch_time has passed since the +first message was received.

+

This step does not require in order processing. If messages are sent +out of order, though, the highest observed offset per partition is +still the committable one, whether or not all messages with lower +offsets have been observed by this step.

+

This strategy propagates MessageRejected exceptions from the +downstream steps if they are thrown.

+
+
Parameters:
+
    +
  • max_batch_size – How many messages should be reduced into one at maximum.

  • +
  • max_batch_time – How much time (in seconds) should be spent reducing +messages together before flushing the batch.

  • +
+
+
+
+
+join(timeout: float | None = None) None
+

Terminates the strategy by joining the following step. +This method tries to flush the current batch no matter +whether the batch is ready or not.

+
+ +
+
+submit(message: Message[FilteredPayload | TStrategyPayload]) None
+

Accumulates messages in the current batch. +A new batch is created at the first message received.

+

This method tries to flush before adding the message +to the current batch. This is so that, if we receive +MessageRejected exception from the following step, +we can propagate the exception without processing the +new message. This allows the previous step to try again +without introducing duplications.

+
+ +
+ +
+
+class arroyo.processing.strategies.batching.UnbatchStep(next_step: ProcessingStrategy[FilteredPayload | TStrategyPayload])
+

This processing step receives batches and explodes them thus sending +the content to the next step message by message.

+

A batch is represented as a ValuesBatch object.

+

If this step receives a MessageRejected exception from the next +step it would keep the remaining messages and attempt to submit +them at the following call to poll

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/commit_offsets.html b/strategies/commit_offsets.html new file mode 100644 index 00000000..3ff8284a --- /dev/null +++ b/strategies/commit_offsets.html @@ -0,0 +1,235 @@ + + + + + + Commit offsets - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Commit offsets

+

Should be used as the last strategy in the chain, to ensure +that offsets are only committed once all processing is complete.

+
+
+class arroyo.processing.strategies.commit.CommitOffsets(commit: Commit)
+

Just commits offsets.

+

This should always be used as the last step in a chain of processing +strategies. It commits offsets back to the broker after all prior +processing of that message is completed.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/filter.html b/strategies/filter.html new file mode 100644 index 00000000..261a5b74 --- /dev/null +++ b/strategies/filter.html @@ -0,0 +1,248 @@ + + + + + + Filter - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Filter

+
+
+class arroyo.processing.strategies.filter.FilterStep(function: Callable[[Message[TStrategyPayload]], bool], next_step: ProcessingStrategy[FilteredPayload | TStrategyPayload], commit_policy: CommitPolicy | None = None)
+

Determines if a message should be submitted to the next processing step.

+

FilterStep takes a callback, function, and if that callback returns +False, the message is dropped.

+

Sometimes that behavior is not actually desirable because streams of +messages is what makes the consumer commit in regular intervals. If you +filter 100% of messages for a period of time, your consumer may not commit +its offsets as a result.

+

For that scenario, you can pass your CommitPolicy to FilterStep. That +will cause FilterStep to emit “sentinel messages” that contain no +payload, but only carry forward partition offsets for later strategies to +commit. Those messages have a payload of type FilteredPayload.

+

For that reason, basically every strategy needs to be able to handle +Message[Union[FilteredPayload, T]] instead of Message[T], i.e. it needs +to subtype ProcessingStrategy[Union[FilteredPayload, TStrategyPayload]]. +If it doesn’t, and rather just handles the regular Message[T], it cannot +be composed with this step, and many other default strategies of arroyo.

+

If no CommitPolicy is passed, no “sentinel messages” are emitted and +downstream steps do not have to deal with such messages (despite the type +system telling them so).

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/healthcheck.html b/strategies/healthcheck.html new file mode 100644 index 00000000..7ea359e8 --- /dev/null +++ b/strategies/healthcheck.html @@ -0,0 +1,291 @@ + + + + + + Healthchecks - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Healthchecks

+

If your code blocks for too long in the main thread, the consumer can turn +unhealthy.

+

Kafka has a setting called max.poll.interval.ms for this that tells Kafka +to kick the consumer out of the broker after this many milliseconds of not polling.

+

You can pass this option into arroyo.backends.kafka.consumer.KafkaConsumer like so:

+
consumer = KafkaConsumer(
+    {
+        "max.poll.interval.ms": 300000, # default 5 minutes
+    }
+)
+
+
+

However, this will not shut down the consumer, it will just keep running doing +nothing (because it is blocked in the main thread). You want a pod-level +healthcheck as well.

+

Arroyo supports touching a file repeatedly from the main thread to indicate +health. Start your pipeline with the +arroyo.processing.strategies.healthcheck.Healthcheck strategy.

+
def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]:
+    ...
+    return message
+
+class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    def __init__(self):
+        self.is_paused = False
+
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        step = RunTask(handle_message, CommitOffsets(commit))
+        return Healthcheck("/tmp/health.txt", step)
+
+
+

The Kubernetes liveness +command would look like:

+
apiVersion: v1
+kind: Pod
+metadata:
+  labels:
+    test: liveness
+  name: liveness-exec
+spec:
+  containers:
+  - name: liveness
+    image: registry.k8s.io/busybox
+    args:
+      - bin/my_arroyo_consumer
+    livenessProbe:
+      exec:
+        command:
+        - rm
+        - /tmp/health.txt
+      initialDelaySeconds: 5
+      periodSeconds: 320  # should be higher than max.poll.interval.ms
+
+
+
+
+class arroyo.processing.strategies.healthcheck.Healthcheck(healthcheck_file: str, next_step: ProcessingStrategy[TStrategyPayload])
+

A strategy that takes a filepath, and touches that file everytime +Strategy.poll is called. If that function is not called multiple times +per minute, it indicates that the consumer is overall unhealthy.

+

File touches are debounced to happen once per second at most.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/index.html b/strategies/index.html new file mode 100644 index 00000000..b822c33f --- /dev/null +++ b/strategies/index.html @@ -0,0 +1,559 @@ + + + + + + Processing Strategies - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Processing Strategies

+

The processing strategies are the components to be wired together to +build a consumer.

+
+

Strategy interface

+

We normally don’t recommend writing your own strategy, and encourage you to use +built-in ones such as “reduce” or “run task” to plug in your application logic. +Nevertheless, all arroyo strategies are written against the following interface:

+
+
+exception arroyo.processing.strategies.abstract.MessageRejected
+

Bases: Exception

+

MessageRejected should be raised in a processing strategy’s submit method +if it is unable to keep up with the rate of incoming messages. It tells +the consumer to slow down and retry the message later.

+
+ +
+
+class arroyo.processing.strategies.abstract.ProcessingStrategy(*args, **kwds)
+

Bases: ABC, Generic[TStrategyPayload]

+

A processing strategy defines how a stream processor processes messages +during the course of a single assignment. The processor is instantiated +when the assignment is received, and closed when the assignment is +revoked.

+

This interface is intentionally not prescriptive, and affords a +significant degree of flexibility for the various implementations.

+
+
+abstract close() None
+

Close this instance. No more messages should be accepted by the +instance after this method has been called.

+

This method should not block. Once this strategy instance has +finished processing (or discarded) all messages that were submitted +prior to this method being called, the strategy should commit its +partition offsets and release any resources that will no longer be +used (threads, processes, sockets, files, etc.)

+
+ +
+
+abstract join(timeout: float | None = None) None
+

Block until the processing strategy has completed all previously +submitted work, or the provided timeout has been reached. This method +should be called after close to provide a graceful shutdown.

+

This method is called synchronously by the stream processor during +assignment revocation, and blocks the assignment from being released +until this function exits, allowing any work in progress to be +completed and committed before the continuing the rebalancing +process.

+
+ +
+
+abstract poll() None
+

Poll the processor to check on the status of asynchronous tasks or +perform other scheduled work.

+

This method is called on each consumer loop iteration, so this method +should not be used to perform work that may block for a significant +amount of time and block the progress of the consumer or exceed the +consumer poll interval timeout.

+

This method may raise exceptions that were thrown by asynchronous +tasks since the previous call to poll.

+
+ +
+
+abstract submit(message: Message[TStrategyPayload]) None
+

Submit a message for processing.

+

Messages may be processed synchronously or asynchronously, depending +on the implementation of the processing strategy. Callers of this +method should not assume that this method returning successfully +implies that the message was successfully processed.

+

If the processing strategy is unable to accept a message (due to it +being at or over capacity, for example), this method will raise a +MessageRejected exception.

+
+ +
+
+abstract terminate() None
+

Close the processing strategy immediately, abandoning any work in +progress. No more messages should be accepted by the instance after +this method has been called.

+
+ +
+ +
+
+class arroyo.processing.strategies.abstract.ProcessingStrategyFactory(*args, **kwds)
+

Bases: ABC, Generic[TStrategyPayload]

+

A ProcessingStrategyFactory is used to wrap a series of +ProcessingStrategy steps, and calls create_with_partitions +to instantiate the ProcessingStrategy on partition assignment +or partition revocation if the strategy needs to be recreated.

+
+
+abstract create_with_partitions(commit: Commit, partitions: Mapping[Partition, int]) ProcessingStrategy[TStrategyPayload]
+

Instantiate and return a ProcessingStrategy instance.

+
+
Parameters:
+
    +
  • commit – A function that accepts a mapping of Partition instances to offset values that should be committed.

  • +
  • partitions – A mapping of a Partition to it’s most recent offset.

  • +
+
+
+
+ +
+
+shutdown() None
+

Custom code to execute when the StreamProcessor shuts down entirely.

+

Note that this code will also be executed on crashes of the strategy.

+
+ +
+ +
+
+

Messages

+
+
+class arroyo.types.BaseValue(*args, **kwds)
+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+replace(value: TReplaced) BaseValue[TReplaced]
+
+ +
+ +
+
+class arroyo.types.BrokerValue(payload: TMessagePayload, partition: Partition, offset: int, timestamp: datetime)
+

A payload received from the consumer or producer after it is done producing. +Partition, offset, and timestamp values are present.

+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property next_offset: int
+
+ +
+
+offset: int
+
+ +
+
+partition: Partition
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+replace(value: TReplaced) BaseValue[TReplaced]
+
+ +
+
+timestamp: datetime
+
+ +
+ +
+
+class arroyo.types.Commit(*args, **kwargs)
+
+ +
+
+class arroyo.types.FilteredPayload
+
+ +
+
+class arroyo.types.Message(value: BaseValue[TMessagePayload])
+

Contains a payload and partitions to be committed after processing. +Can either represent a single message from a Kafka broker (BrokerValue) +or something else, such as a number of messages grouped together for a +batch processing step (Payload).

+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+property payload_unfiltered: TMessagePayload
+
+ +
+
+replace(payload: TReplaced) Message[TReplaced]
+
+ +
+
+value: BaseValue[TMessagePayload]
+
+ +
+ +
+
+class arroyo.types.Partition(topic: 'Topic', index: 'int')
+
+
+index: int
+
+ +
+
+topic: Topic
+
+ +
+ +
+
+class arroyo.types.Topic(name: 'str')
+
+
+name: str
+
+ +
+ +
+
+class arroyo.types.Value(payload: TMessagePayload, committable: Mapping[Partition, int])
+

Any other payload that may not map 1:1 to a single message from a +consumer. May represent a batch spanning many partitions.

+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+replace(value: TReplaced) BaseValue[TReplaced]
+
+ +
+ +
+
+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/produce.html b/strategies/produce.html new file mode 100644 index 00000000..62c094d2 --- /dev/null +++ b/strategies/produce.html @@ -0,0 +1,241 @@ + + + + + + Produce - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Produce

+
+
+class arroyo.processing.strategies.produce.Produce(producer: Producer[TStrategyPayload], topic: Topic, next_step: ProcessingStrategy[FilteredPayload | TStrategyPayload], max_buffer_size: int = 10000)
+

This strategy can be used to produce Kafka messages to a destination topic. A typical use +case could be to consume messages from one topic, apply some transformations and then output +to another topic.

+

For each message received in the submit method, it attempts to produce a single Kafka message +in a thread. If there are too many pending futures, we MessageRejected will be raised to notify +stream processor to slow down.

+

On poll we check for completion of the produced messages. If the message has been successfully +produced then the message is submitted to the next step. If an error occured the exception will +be raised.

+

Important: The destination topic is always the topic passed into the constructor and not the +topic being referenced in the message itself (which typically refers to the original topic from +where the message was consumed from).

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/reduce.html b/strategies/reduce.html new file mode 100644 index 00000000..cd23f98a --- /dev/null +++ b/strategies/reduce.html @@ -0,0 +1,269 @@ + + + + + + Reduce (Fold) - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Reduce (Fold)

+

Accumulate messages based on a custom accumulator function

+
+
+class arroyo.processing.strategies.reduce.Reduce(max_batch_size: int, max_batch_time: float, accumulator: Callable[[TResult, BaseValue[TPayload]], TResult], initial_value: Callable[[], TResult], next_step: ProcessingStrategy[TResult])
+

Accumulates messages until the max size or max time condition is hit. +The accumulator function is run on each message in the order it is received.

+

Once the “batch” is full, the accumulated value is submitted to the next step.

+

This strategy propagates MessageRejected exceptions from the +downstream steps if they are thrown.

+
+
Parameters:
+
    +
  • max_batch_size – How many messages should be reduced into one at maximum.

  • +
  • max_batch_time – How much time (in seconds) should be spent reducing +messages together before flushing the batch.

  • +
+
+
+
+
+join(timeout: float | None = None) None
+

Terminates the strategy by joining the following step. +This method tries to flush the current batch no matter +whether the batch is ready or not.

+
+ +
+
+submit(message: Message[FilteredPayload | TPayload]) None
+

Accumulates messages in the current batch. +A new batch is created at the first message received.

+

This method tries to flush before adding the message +to the current batch. This is so that, if we receive +MessageRejected exception from the following step, +we can propagate the exception without processing the +new message. This allows the previous step to try again +without introducing duplications.

+
+ +
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/run_task.html b/strategies/run_task.html new file mode 100644 index 00000000..ac0a066d --- /dev/null +++ b/strategies/run_task.html @@ -0,0 +1,232 @@ + + + + + + Run Task - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Run Task

+
+
+class arroyo.processing.strategies.run_task.RunTask(function: Callable[[Message[TStrategyPayload]], TResult], next_step: ProcessingStrategy[FilteredPayload | TResult])
+

Basic strategy to run a custom processing function on a message.

+

The processing function provided can raise InvalidMessage to indicate that +the message is invalid and should be put in a dead letter queue.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/run_task_in_threads.html b/strategies/run_task_in_threads.html new file mode 100644 index 00000000..9c1d5899 --- /dev/null +++ b/strategies/run_task_in_threads.html @@ -0,0 +1,239 @@ + + + + + + Run Task in Threads - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Run Task in Threads

+
+
+class arroyo.processing.strategies.run_task_in_threads.RunTaskInThreads(processing_function: Callable[[Message[TStrategyPayload]], TResult], concurrency: int, max_pending_futures: int, next_step: ProcessingStrategy[FilteredPayload | TResult])
+

This strategy can be used to run IO-bound tasks in parallel.

+

The user specifies a processing function (a callable that takes a message). For each message received +in the submit method, it runs that processing function. Once completed, the message is submitted +to the next step (with the payload containing the result of the processing function).

+

Since the processing function will be run in threads, avoid using objects which can be modified +by different threads or protect it using locks.

+

If there are too many pending futures, we MessageRejected will be raised to notify the stream processor +to slow down.

+

On poll we check for completion of futures. If processing is done, we submit to the next step. +If an error occured the original exception will be raised.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/run_task_with_multiprocessing.html b/strategies/run_task_with_multiprocessing.html new file mode 100644 index 00000000..5587b564 --- /dev/null +++ b/strategies/run_task_with_multiprocessing.html @@ -0,0 +1,353 @@ + + + + + + Run Task with Multiprocessing - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Run Task with Multiprocessing

+
+
+class arroyo.processing.strategies.run_task_with_multiprocessing.RunTaskWithMultiprocessing(function: Callable[[Message[TStrategyPayload]], TResult], next_step: ProcessingStrategy[FilteredPayload | TResult], num_processes: int, max_batch_size: int, max_batch_time: float, input_block_size: int | None = None, output_block_size: int | None = None, max_input_block_size: int | None = None, max_output_block_size: int | None = None, initializer: Callable[[], None] | None = None)
+

Run a function in parallel across messages using subprocesses.

+

RunTaskWithMultiprocessing uses the multiprocessing stdlib module to +transform messages in parallel.

+
+
Parameters:
+
    +
  • function – The function to use for transforming.

  • +
  • next_step – The processing strategy to forward transformed messages to.

  • +
  • num_processes – The number of processes to spawn.

  • +
  • max_batch_size – Wait at most for this many messages before “closing” a batch.

  • +
  • max_batch_time – Wait at most for this many seconds before closing a batch.

  • +
  • input_block_size

    For each subprocess, a shared memory buffer of +input_block_size is allocated. This value should be at least +message_size * max_batch_size large, where message_size is the expected +average message size.

    +

    If the value is too small, the batch is implicitly broken up. In that +case, the +arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow +metric is emitted.

    +

    If the value is set to None, the input_block_size is automatically +adjusted to adapt to traffic. Keep in mind that this is a rather +experimental feature and less productionized than explicitly setting a +value.

    +

  • +
  • output_block_size

    Size of the shared memory buffer used to store +results. Like with input data, the batch is implicitly broken up on +overflow, and +arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow +metric is incremented.

    +

    Like with input_block_size, the value can be set to None to enable +automatic resizing.

    +

  • +
  • max_input_block_size – If automatic resizing is enabled, this sets an +upper limit on how large those blocks can get.

  • +
  • max_output_block_size – Same as max_input_block_size but for output +blocks.

  • +
  • initializer

    A function to run at the beginning of each subprocess.

    +

    Subprocesses are spawned without any of the state of the parent +process, they are entirely new Python interpreters. You might want to +re-initialize your Django application here.

    +

  • +
+
+
+
+

Number of processes

+

The metric +arroyo.strategies.run_task_with_multiprocessing.batches_in_progress +shows you how many processes arroyo is able to effectively use at any given +point.

+

The metric arroyo.strategies.run_task_with_multiprocessing.processes +shows how many processes arroyo was configured with.

+

If those two metrics don’t line up, your consumer is not bottlenecked on +number of processes. That’s a good thing, you want to have some reserve +capacity. But it means that increasing num_processes will not make your +consumer faster.

+
+
+

Batching

+

Arroyo sends messages in batches to subprocesses. max_batch_size and max_batch_time +should be tweaked for optimal performance. You can observe the effect in the following metrics:

+
    +
  • arroyo.strategies.run_task_with_multiprocessing.batch.size.msg: The number of messages per batch.

  • +
  • arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes: The number of bytes used per batch.

  • +
+

The cost of batches (locking, synchronization) generally amortizes with +increased batch sizes. Too small batches, and this strategy will spend a +lot of time synchronizing between processes. Too large batches, however, +can cause your consumer to not use all processes effectively, as a lot of +time may be spent waiting for batches to fill up.

+

If batch.size.msg is flat (as in, it’s a perfectly straight line at a +constant), you are hitting max_batch_size. If batch.size.bytes is +flat, you are hitting input buffer overflow (see next section). If neither +are flat, you are hitting max_batch_time.

+
+
+

Input and output buffers

+

You want to keep an eye on these metrics:

+
    +
  1. arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow

  2. +
  3. arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow

  4. +
  5. arroyo.strategies.run_task_with_multiprocessing.batch.backpressure

  6. +
+

If batch.input.overflow is emitted at all, arroyo ran out of memory for +batching and started breaking up your batches into smaller ones. You want +to increase input_block_size in response. Note that when you do this, +you may have to re-tweak max_batch_size and max_batch_time, as you +were never hitting those configured limits before. Input overflow is not +really all that expensive in Arroyo, but since it affects how batching +works it can still make performance tuning of your consumer more confusing. +Best to avoid it anyway.

+

If batch.output.overflow is emitted at all, arroyo ran out of memory +when fetching the data from subprocesses, and so the response from +subprocesses to the main processes is chunked. Output overflow is very +expensive, and you want to avoid it. Increase output_block_size in +response.

+

If batch.backpressure is continuously emitted, you are not bottlenecked +on multiprocessing at all, but instead the next strategy can’t keep up and +is applying backpressure. You can likely reduce num_processes and won’t +notice a performance regression.

+
+
+

How to tune your consumer

+

Note that it doesn’t make sense to fix output overflow without fixing input +overflow first. If you increase output block size to get rid of output +overflows, then increase input block size, your effective batch size may +increase to a point where you encounter output overflow again. If you +encounter a lot of issues at once, best to fix them in this order:

+
    +
  1. First, tune input_block_size to fix input overflow. This will +increase average/effective batch size.

  2. +
  3. Then, tune max_batch_size and max_batch_time so that you get the +highest throughput. Test this by running your consumer on a backlog of +messages and look at consumer offset rate, or time it takes to get consumer +lag back to normal.

  4. +
  5. Then, tune output_block_size to fix output overflow. If in your +previous tests there was a lot of output overflow, this will remove a lot +of CPU load from your consumer and potentially also increase throughput.

  6. +
  7. Now take a look at the batch.backpressure metric. If it is emitted, +you need to optimize the next strategy (next_step) because that’s what +you’re bottlenecked on. If it is not emitted, you may need to increase +num_processes or increase batch size.

  8. +
+
+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/unfold.html b/strategies/unfold.html new file mode 100644 index 00000000..5f20a2a4 --- /dev/null +++ b/strategies/unfold.html @@ -0,0 +1,238 @@ + + + + + + Unfold - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Unfold

+

Generates a sequence of messages from a single message based on a custom generator function

+
+
+class arroyo.processing.strategies.unfold.Unfold(generator: Callable[[TInput], Collection[TOutput]], next_step: ProcessingStrategy[FilteredPayload | TOutput])
+

Unfold receives a message and explodes it to generate a collection of +messages submitting them one by one to the next step. The generated +messages are created according to the generator function provided by the user.

+

The generator function provided must return a collection (i.e. a class that +implements sized + iterable).

+

If this step receives a MessageRejected exception from the next +step it keeps the remaining messages and attempts to submit +them on subsequent calls to poll

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/what_for.html b/what_for.html new file mode 100644 index 00000000..60193bf3 --- /dev/null +++ b/what_for.html @@ -0,0 +1,482 @@ + + + + + + What is Arroyo for? - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

What is Arroyo for?

+

Arroyo is a library for writing high-throughput, testable kafka +consumers and producers. This document attempts to outline the +intricacies of writing such consumers.

+
+

Goals

+
    +
  1. Make it easy to build consumers that provide delivery guarantees

  2. +
  3. Make it easy to write high-throughput kafka consumers

  4. +
  5. Make it easy to write reliable, high throughput kafka producers

  6. +
  7. Abstract away rebalancing such that users of the library do not have +to worry about it

  8. +
  9. Make it possible to test kafka consumer logic without having to +reproduce the entire kafka environment

  10. +
  11. Provide a way for the application logic to signal backpressure

  12. +
+
+
+

Why Simple Doesn’t Cut It

+

When visualizing event-driven architecture, Kafka is viewed as an +abstract queue with groups of producers pushing to it, and consumers +consuming from it (as in the diagram below).

+
+ graph TD + Producer --> Kafka_Topic + Kafka_Topic --> Consumer + Consumer --> Destination +

A more accurate model is that kafka is like a log file which is +persistent and there are offsets of the file that different consumers +have read or not read.

+

The most simple kafka consumer looks something like this:

+
from confluent_kafka import Consumer
+
+conf = {
+    "bootstrap.servers": "localhost:9092",
+    "group.id": "my_group",
+    "auto.offset.reset": "latest",
+}
+
+consumer = Consumer(conf)
+consumer.subscribe(["my_topic"])
+
+while True:
+    message = consumer.poll()
+    send_to_destination(process_message(message))
+
+
+

This simple consumer would not satisfy the goals mentioned at the top of +this page. The following subsections will explain why

+
+
+

Providing delivery guarantees

+

By default, a consumer in the confluent_kafka library will +auto-commit on poll. To understand what it means to commit to a kafka +topic, see the Appendix. This can lead to the following issue:

+
# get message from kafka, commit immediately
+message = consumer.poll()
+# ❗❗❗ throws exception due to a network issue
+send_to_destination(process_message(message))
+# this message is now lost and we're on to the next one
+
+
+

This can be fixed by only committing after we know that the message has +reached its destination in the following way:

+
# add this value to the config:
+"enable.auto.commit": "false"
+# -------
+message = consumer.poll(timeout=0)
+send_to_destination(process_message(message))
+consumer.commit(message.offset())
+
+
+
+
+

High Throughput

+

The previous section has allowed us to not commit messages that are not +processed however committing every message severely hurts throughput. +Every call to commit is a network operation, it also makes the broker +persist and replicate the information. If we can reduce the number of +commit calls, our throughput can be much higher. And so we commit in +batches

+
# this code is purely descriptive.
+# We have to commit to each partition separately
+# but that code is not helpful for this example
+message = consumer.poll(timeout=0)
+batch.append(process_message(message))
+if len(batch) == batch_size:
+    consumer.commit(offsets=[m.offset() for m in batch])
+
+
+

This will get us faster throughput however we are currently hand-waving +away how we send the message to its destination

+
+
+

Reliable High Throughput Batched Producers

+

Producing to Kafka reliably and at high throughput is not a simple +operation. Here is how a simple Kafka Producer looks in code:

+
from confluent_kafka import Producer
+
+conf = {
+  "bootstrap.servers": "localhost:9092",
+}
+producer = Producer(conf)
+def send_to_destination(message):
+    # ❗ This does not do what it says
+    # it writes to a buffer
+    producer.produce("destination_topic", message)
+    # this will actually block until the messages are produced
+    # calling this after produce every time is very expensive,
+    # how often we flush has high impacts on the producer throughput
+    producer.flush()
+
+
+

At a high level, the producer is actually buffering the messages +produced to the topic

+_images/kafka_producer.png +

A kafka producer writes to an internal buffer. This batches the IO +(good) but you don’t know when it will ever make it to the +destination

+

In order to allow for reliability of transmission, the +confluent_kafka library provides a callback to +produce +like so

+
def delivery_callback(error, message):
+    # do something here to make sure your message is in the state
+    # you want it to be
+
+producer.produce("destination_topic", message, on_delivery=delivery_callback)
+
+
+
+
+

Dealing With Rebalancing

+
+

What is Rebalancing

+

A kafka topic is divided into n partitions, each partition can be +consumed by exactly one consumer per consumer +group. A consumer can +consume multiple partitions

+
+_images/consumer_groups.png +
+
+
+

When Rebalancing Can Happen

+

Rebalancing can happen due to:

+
    +
  • An addition or removal of a consumer to a consumer group

    +
      +
    • (Every deploy does this)

    • +
    +
  • +
  • A rebalance being kicked off manually

  • +
  • A consumer pod dies and now its partition needs to be re-assigned

  • +
  • Whenever the broker decides it’s a good idea (it can happen at any +time)

  • +
  • TODO: More things?

  • +
+
+
+

How Rebalancing Affects a Consumer

+

Rebalancing is annoying to handle for a consumer that processes batches, +imagine the following scenario:

+
+ sequenceDiagram + Broker->>Consumer: message + activate Consumer + note right of Consumer: start building batch + Broker->>Consumer: message + Broker->>Consumer: Revoke Partition + deactivate Consumer + Consumer->>Broker: commit batch + note left of Broker: Received commit from revoked Consumer! +

Once a partition is revoked for a consumer, it cannot commit to it. This +is bad news for the batch that the consumer has built up. Each consumer +has different requirements but a decision has to be made as to whether +to flush the batch or to discard its work and let the next consumer +assigned to this partition pick it up. The rebalancing behavior can be +customized by providing an on_revoke callback to the consumer when +subscribing.

+
from confluent_kafka import Consumer
+
+conf = {
+    "bootstrap.servers": "localhost:9092",
+    "group.id": "my_group",
+    "auto.offset.reset": "latest",
+}
+
+def flush_current_batch(consumer, partitions):
+    # flush the current batch
+    pass
+
+consumer = Consumer(conf)
+consumer.subscribe(["my_topic"], on_revoke=flush_current_batch)
+
+
+
+
+
+

librdkafka’s Callback Hell

+

librdkafka uses callbacks as a core mechanic for control flow. A few +such examples have been mentioned in this document already. What is not +clear however, is that callbacks are only called when ``poll`` is +called

+

This means that:

+
    +
  • this line could possibly do a lot of work:

  • +
+
# any scheduled callbacks will run within this call
+message = consumer.poll()
+
+
+
    +
  • No callbacks will be invoked until the consumer or producer call +poll again (for their respective callbacks)

  • +
  • poll has to be called periodically on a consumer otherwise the +broker will kick the consumer out of the consumer group

    +
      +
    • The handling of that revocation won’t happen until poll is +called

    • +
    +
  • +
+
+
+

Conclusion

+

There are many intricacies and gotchas to writing high performant, +reliable kafka consumers. This document does not outline all of them but +all of what is outlined here should be kept in mind when designing any +kafka consumer library.

+
+
+

Appendix

+
+
+

Committing to a Kafka Topic

+

A consumer comitting to a topic signals to the broker that this message +has been processed. When poll is called next by that consumer, it +will return the next message.

+

API +Doc

+
+
+

What is a Kafka Consumer Group

+

https://www.educba.com/kafka-consumer-group/

+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file