ZeroMQ používáme k naprosté spokojenosti. Konkrétně ROUTER/DEALER sockety - oproti REQ/REP mají tu výhodu, že odpověď se nemusí skládat jen z jedné message, ale může jich být víc, takže si můžu signalizovat, že request dorazil skrz broker na cílový service worker (klient si pak může prodloužit timeout), a teprve v další message mi přijde odpověď. Nebo si si tu odpověď můžu streamovat ve více messages. (Tip: přestože to jde, nedělejte gigabajtové zmq message...) Pro vnitrofiremní "microservices" komunikaci mi něco takového dává mnohem větší smysl, než HTTP (to si nechte na veřejné API).
V Pythonu si pyzmq rozumí i s asyncio. Donedávna bylo potřeba instalovat pyzmq-specific event loop místo defaultní asyncio event loop a to nebylo úplně kompatibilní např. s web frameworky, ale v poslední verzi pyzmq už je tato praktika deprecated a pyzmq si už rozumí i s default asyncio event loop.
Jo a přečtěte si zguide :) http://zguide.zeromq.org/page:all Ppřípadně verze s příklady v Pythonu místo C: http://zguide.zeromq.org/py:all
Spinoff ZMQ je https://nanomsg.org/ psaný v C. "by Martin Sustrik (inventor of both nanomsg and ZeroMQ)"
To se me na Martinovi libi - napsal blogpost o tom, proc nemel psal ZMQ v C++ (http://250bpm.com/blog:4, http://250bpm.com/blog:8) a nezustal jen u bogu, protoze to fakt prepsal.
To je ten člověk, co nadává na C++ a přitom tomu nerozumí? Konkrétněji: Říká, že má problém s výjimkami. Ve skutečnosti má problém s detekcí a ošetřováním chyb. Je celkem jedno, jestli to budu dělat návratovými kódy, globální proměnnou, nebo výjimkou. Neošetřená výjimka a zabití procesu tedy není problém C++, ale problém programátora. Stejně tak mohl neošetřit návratový kód nebo globální proměnnou. Další problém má se spojovým seznamem. Prosím nikdy nepoužívejte (místo hranatých závorek si představte špičaté, nevím, co by se špičatými napáchal místní redakční systém) std::list[person*], raději zvolte std::vector[person*] nebo std::list[person]. Smazání objektu ze seznamu má v C++ složitost O(1), pokud mám k dispozici iterátor. Mít jeden objekt ve více seznamech najednou lze řešit pomocí std::shared_ptr[person]. Marek.
viz https://en.wikipedia.org/wiki/Pieter_Hintjens
a https://sdtimes.com/code-editor/sd-times-blog-zeromq-founder-pieter-hintjens-dies/
velmi zajime čtení o AMQ a RedHatu je take http://hintjens.com/blog:125#toc13
V principu je to tak, akorat, ze jsem jeste posbiral nekolik dalsich napadu a zapsal je od jednoho skriptu.
Co se tyce zajmu - pokud nekdo taky potrebuje commandline nastroj, kterym si debuguje nejaky ten svuj kod, tak ma stejnej problem, jako jsem mel ja. github.com/jaromrax/nczmq . No a pokud by to nekdo chtel nekam posunout, tak pro me jen dobry.
Teda nezlob se na mě, ale ten kód by neměl nikomu sloužit jako inspirace. Když jsem na to pustil linter, tak jsem myslel že vybuchne, sto errorů a 26 warning, to nemluvím o logických chybách.
Kdybys tam měl těch chyb míň, tak bych ti na to asi napsal nějaký code review řádku po řádce, ale tohle kromě toho že to nějak funguje, je po všech ostatních ohledech ukázka toho, jak by se v pythonu neprogramuje. Od syntaxe, kterou píšeš blbě (koukni se co je to PEP8), po to že to máš celé rozpláclé na úrovni modulů a smíchané s user-interfacem. Inicializace argumentů by měla být v if __name__ == "__main__", jinak se inicializují vždycky když to chceš importovat. Celé by to mělo být rozlámané do funkcí. Ty inline ify jsou prasárna, která jen ubírá na čitelnosti. Tohle fakt ne; if EXITME:quit. Nejen že je to nečitelná prasárna, ale chybí ti tam závorky, quit je volání funkce. Snažíš se ušetřit budget za řádek, nebo co?
Dokumentační komentáře se takhle v pythonu nedělaj. Když odychátáváš výjimky, tak na ně taky reaguj jinak než vypsáním že došlo k chybě - kód pak normálně pokračuje a padne o řádek dál, takže to bylo celé úplně k ničemu.
Nauč se používat logging a nastavuj debug level v něm, pokud chceš debug hlášky. Těch sto if podmínek tam všude je .. fakt špatně. Kdyby to mělo k něčemu být, tak bys to měl rozdělit do menších funkcí. Jenže celé to jen používá základní api volání zmq, takže si neumím představit, že by to k něčemu bylo.
Jako já nemám nic proti tomu že sis to tak napsal, každej nějak testuje, ale měj soudnost a nedělej z toho příklady na netu.
Diky za zpetnou vazbu. Pylint jsem neznal, velmi zajimave. Legracni jsou ty zakazy mezer a naming style, dobry jsou ty upozorneni na redefinice apod. Kulturu programovani v pythonu skutecne neznam a nektere praktiky budou nadmiru uzitecne. To byla ta zajimava cast.
Ta druha cast je vlastne taky zajimava, ale takovym jinym zpusobem
- Ze si neumis predstavit, ze by to k necemu bylo : je v poradku, kdyz to nevidis, dalo by se to asi resit dotazem.
- Jestlis mel pocit, ze tu prezentuji nejake priklady na netu, tak to byl spatny pocit, nevim, cim jsem ho mohl vyvolat. Opakovat myslenku, ze postradam neco jako nc se superpowers uz dal nebudu.
Kdyz zhodnotim svuj pokus - vlastne se potkavam casto se situaci, kdy se lide fixuji na formu a myslenka jim utece, takze prekvapen nejsem. Pozitivni reakci nevidim, pohorseni budit za kazdou cenu nemusim. Tak snad nekdy jindy na nejakem jinem foru.
> Diky za zpetnou vazbu. Pylint jsem neznal, velmi zajimave. Legracni jsou ty zakazy mezer a naming style, dobry jsou ty upozorneni na redefinice apod. Kulturu programovani v pythonu skutecne neznam a nektere praktiky budou nadmiru uzitecne. To byla ta zajimava cast.
Pylint, pyflakes, pep8, sonarlint. Doporučuju všechny čtyři utility najednou.
> - Ze si neumis predstavit, ze by to k necemu bylo : je v poradku, kdyz to nevidis, dalo by se to asi resit dotazem.
To bylo myšleno v kontextu repozitáře. Je mi asi jasné, že tobě to k něčemu bude, ale aby to mohl člověk použít, tak by toho musel přepsat tolik, že je mnohem jednodušší to napsat prostě na zelené louce.
> - Jestlis mel pocit, ze tu prezentuji nejake priklady na netu, tak to byl spatny pocit, nevim, cim jsem ho mohl vyvolat. Opakovat myslenku, ze postradam neco jako nc se superpowers uz dal nebudu.
Tak když přijdeš do diskuze a doslova to nabídneš jako ukázku, tak se těžko můžeš divit, že takový pocit mám, že.
> Kdyz zhodnotim svuj pokus - vlastne se potkavam casto se situaci, kdy se lide fixuji na formu a myslenka jim utece, takze prekvapen nejsem. Pozitivni reakci nevidim, pohorseni budit za kazdou cenu nemusim. Tak snad nekdy jindy na nejakem jinem foru.
Hele, děláš úplně klasickou chybu, kdy se ztotožňuješ se svým kódem. Tu myšlenku chápu. Je jasná a nevidím na ní nic co by stálo za zmínku, ale to je můj problém a ostatně myšlenku jsem vůbec nekritizoval. Kód má mnoho rozměrů kvality. I kdyby ta myšlenka byla sebekvalitnější, tak dimenze architektury, rozložení, čitelnosti a pár dalších už kvalitní vážně nejsou. A já tě přeci nehejtuji, snažím se tě na to pouze relativně konstruktivně upozornit, píšu to slušně, vypíchl jsem body co mi konkrétně přijdou nedostatečné a tak. To si neber jako útok na tvojí osobu.
Za me v klidu. Zkusil jsem najit nekoho se stejnym zajmem a vyssi kulturou kodovani. A nasel nekoho s vyssi kulturou kodovani.
Nerad davam rady, ale po poslednim odstavci mam pocit, ze jednu zkusim. Jestli Te mrzi zes byl mozna trochu "vostrej" tak napis "promin", je to strucny, chlapsky a (s normalnimi lidmi) to vyborne funguje. Jestli citis formu kritiky adekvatni, ja s Tvym pocitem problem nemam, beru Te jakej jsi a vysvetlovat nic nepotrebuju. Treti moznost je, ze jen chces zmenit moji reakci - pak sam vidis, ze stejne maris cas.
Za mě se z pythonu stává jazyk který se dá slušně reviewovat, až když je to správně i podle mypy. Nuti to totiz myslet o tom jakeho je ktera promenna typu a tedy si spravne typy rozvrhnout. A pokud si clovek nadefinuje semanticke typy (jednoduchy priklad: Name, Surname) ze stejneho zakladniho typu, tak mu to pak muze kontrolovat, ze napriklad omylem neprohodil treba parametry funkce (greet_person(surname, name)).
Uz to zminoval Messa, ale pro mne to bylo velke prekvapeni pri pokusu o integraci s Flaskem: ZMQ funguje nad event loop, ktera monkey-patchuje I/O operace (zejmena sockety) v zakladni knihovne - byval to gevent, ted uz zrejme i dalsi. To znamena, ze jakmile ve Flaskove aplikaci (ktera spoleha na klasickou implementaci s prefork/threadpool workerama) udelam import zmq, tak se mi patchne socket a mam smulu => zmq neni kompatibilni a ZMQ komunikaci (napr. distribuci tasku z API na workery na nichz mi bezi nejaky machine learning) si musim provozovat v samostatnem procesu/interpretu Pythonu, oddelenem od weboveho API.
Dalsi prekvapko pro me bylo, ze kdyz jsem se z guidu docetl, ze jakmile v ZMQ odpojim subscribera (napr. prevysadim novou verzi me microservice), tak mu utecou vsechny zpravy ktere mezitim nekdo publikoval. Podobne ze pokud zacnu driv publikovat nez konzumovat, tak prijdu o zpravy ktere byly v mezicase publikovane. Tedy hodne jine chovani, nez u pub-sub s perzistenci, jako je napr. Kafka. Cili s tim chce pocitat pri navrhu a dobre si precist vsechny ty lazy pirate patterny a spol. (publisher si hlida, ze mu prislo potvrzeni o prijeti zpravy a kdyztak ji znova publikuje) v dokumentaci ZMQ.
A treti prekvapko pro me bylo, ze nad ZMQ nemuzu provozovat HTTPS - pokud chci sifrovat, tak bud si pro kazdy komunikacni kanal budu udrzovat point-to-point SSL tunel (a hlidat si, ze se nerozpadl, coz u velkeho poctu spojeni a M:N komunikace neni nic moc), nebo musim pouzit custom sifrovani ze ZMQ nadstavby pomoci eliptickych krivek, coz muze narazit na securitaky (ne ze by to nebylo bezpecne, ale nemaji to v korporatu na seznamu schvalenych technologii a kvuli ZMQ ho rozsirovat nehodlaji) a pokud dodavam externim zakaznikum tak me to muze znevyhodnovat ve vyberovem rizeni/RFP.
Kdyztak me pls nekdo doplnte/opravte, naposledy jsem se o ZMQ zajimal pred dvema lety a spousta se toho mohla od te doby zmenit.
ty druhe dva body vyresite nasazenim normalniho message brokera - RabbitMQ, AMPQ, SQS, RQ. Pokud vam fakt staci message fronty a nejake zakladni pipeline, nema smysl IMHO pouzivat knihovnu urcenou na neco trosku jineho. Ten prvni je asi hodne relevantni, ale my to pouzivame s C/C++, kde takovy problemy nejsou (proste si ZMQ udela vlastni vlakno, ale o tom vlastne ani nemusime vedet).
Zalezi na vyuziti, zmq/czmq je vcelku solidny blackbox - nemate kontrolu na frontou, neviete kolko zaznamov sa posiela do siete alebo kolko zaznamov zo siete caka na spracovanie, ak aplikacia nepadne na race condisnu/assert, tak sa stava ze dojde pamat. Potom sa hodi poupravit kod a pocitat, kolko zaznamov je v yqueue (src/yqueue.hpp) a pripadne nastavit hwm (ak nevadi, ze zmq obcas nieco vyhodi), nech sa vie korelovat, ktora komponenta je aktivna, kym fronty yqueue narastaju. Dopatrat sa, ktory konkretny zmq socket za tym stoji je uz komplikovanejsie.