Прыклад уцечкі гаразуты і як адладзіць яе

Калі я набліжаюся да функцыі, якая аб'ядноўвае ў сабе фрагмент кода ў праграме і сувязь / адмена пры дапамозе каналаў, я звычайна спакушаю паглядзець глыбей, бо гэта цудоўнае месца, каб укараніць уцечку goroutine даволі лёгка, і гэтыя памылкі даволі лёгка прапусціць нават распрацоўшчыка голанга для пачаткоўцаў. І вось што я зрабіў для гэтага кода, які я знайшоў у KUDO.

Што такое ўцечка сістэмы?

У асноўным уцечка памяці - гэта ўцечка памяці. Вы запускаеце праграму, але яна ніколі не спыніцца, назаўжды займаючы памяць, якую яна захавала. Каб спрасціць прыклад, які я размясціў з KUDO, гэта прыклад таго, як можна ўкараніць уцечку гарауты ў свой праект.

Код робіць тое, што ў гарадовай праграме ёсць прымусовы тайм-аут і перыядычная аперацыя. Кожны галачка мы спрабуем праверыць нейкую дзелавую логіку (сцвярджаем, што нешта здаровае / напрыклад, гатова) - у гэтым прыкладзе ён проста імітуе гэты званок, высыпаючыся, а потым вяртаючыся.

Дык дзе ўцечка? У спрошчаным прыкладзе вышэй, час чакання складае ўсяго 1 секунду, а аперацыя праверкі займае 10 секунд. Гэта азначае, што гэты тэрмін спачатку будзе выкананы, вярнуўшыся з "waitReady". Прыкладна праз 9 секунд наша сістэма атрымлівае вынік ад праверкі і спрабуе запісаць у doneChan. Пішыце на незабяспечаны канал, ён блакуе, і ніхто не слухае гэты канал, таму што мы ўжо вярнуліся з waitReady - і вось наша ўцечка!

Як даведацца, ці ёсць у вас уцечка goroutut?

Наогул кажучы, пакет "Runtime" - гэта ваш сябар тут. Адзін са спосабаў выкарыстання runtime.NumGoroutine () у тэсце да і пасля выкліку функцыі waitReady. Калі колькасць гарадскіх рэжымаў да чаканняReady і пасля не супадае, у вас ёсць уцечка.

Яшчэ адзін варыянт - гэта выкарыстанне бібліятэкі з Uber - goleak. Калі вы пагрузіцеся ў тое, як рэалізаваны той, ён таксама абапіраецца на пакет выканання, на гэты раз ён счытвае ўсе стэкі (runtime.Stack функцыя) і ў дадатак да гэтага ўводзіць пару зручных метадаў.