Näide gorutiinist lekke kohta ja kuidas seda siluda

Kui lähenen funktsioonile, mis ühendab kooditüki käitamise gorutiinis ja suhtlust / tühistamist kanalite abil, on mul enamasti kiusatus vaadata sügavamalt, sest see on suurepärane koht gorutiinilekke tutvustamiseks üsna hõlpsalt ja neid vigu on üsna kerge tuvastada. igatsed isegi mitte algaja golangi arendaja järele. Ja seda ma tegin selle kooditüki jaoks, mille KUDO-st leidsin.

Mis on gorutiini leke?

Gorutiini lekkimine on põhimõtteliselt mälulekke tüüp. Alustate gorutiini, kuid see ei lõpe kunagi, hõivates igavesti talletatud mälu. KUDO postitatud näite pisut lihtsustamiseks on see näide sellest, kuidas nende projekti sisse viia goroutine leke.

Kood teeb vaid seda, et gorutiinis toimiks sunnitud aegumine ja perioodiline toiming. Iga linnukese abil proovime kontrollida mõnda äriloogikat (väita, et midagi on tervislik / näiteks valmis) - selles näites simuleerib see lihtsalt seda kõnet magades ja siis tagasi pöördudes.

Niisiis, kus on leke? Ülaltoodud lihtsustatud näites on ajalõpp vaid 1 sekund, samal ajal kui kontrolltoiming võtab 10 sekundit. See tähendab, et tähtaega hakatakse täitma kõigepealt, naastes saidilt "waitReady". Umbes 9 sekundit hiljem saab meie goroutine kontrollijalt tulemuse ja proovib kirjutada doneChani. Puhverdamata kanalile kirjutamine blokeerib ja keegi seda kanalit ei kuula, kuna naasime juba ooteajaltReady - ja siin on meie leke!

Kuidas teada saada, kas teil on gorutiini leke?

Üldiselt öeldes on käituspakett teie sõber. Üks viis on runtime.NumGoroutine () kasutamine testis enne ja pärast funktsiooni waitReady kutsumist. Kui enne ootamistReady ja pärast seda pole gorutiinide arv sama, siis on teil leket.

Teine võimalus on kasutada raamatukogu Uber - goleakist. Kui mõelda selle rakendamisse, siis tugineb see ka käituspaketile, seekord loeb see kõik korstnad (funktsioon runtime.Stack) ja tutvustab sellele lisaks mõnda mugavusmeetodit.