Go 채널 패턴 - 드롭

Go 프로그래밍 기술을 향상하고 더 나은 Go 엔지니어가 되기 위해 최근에 Ardan Labs에서 우수한 주문형 교육을 구입했습니다. 재료는 Go 전문 엔지니어인 .






빌 케네디 : MIA/-5


@goinggodotnet






와의 대화를 확인하세요. 그는 기술 채용 담당자가 되는 비즈니스를 어떻게 키웠는지에 대한 정말 흥미로운 이야기를 들려줍니다. 내가 아는 최고 중 하나입니다. ardanlabs.buzzsprout.com/1466944/968101…


오후 15:18 - 2021년 12월 9일









저는 Go 모범 사례와 설계 철학에 따라 더 관용적인 코드를 작성하는 방법을 배우는 과정을 기록하기로 결정했습니다.

이 게시물 시리즈는 고루틴을 통한 Go의 오케스트레이션/신호에 사용되는 채널 패턴을 설명합니다.

드롭 패턴



드롭 패턴의 주요 아이디어는 주어진 순간에 수행할 수 있는 작업량에 제한을 두는 것입니다.



우리는:
  • 신호 시맨틱을 제공하는 버퍼링된 채널
  • 작업자 고루틴의 수
  • 다음과 같은 관리자 고루틴:
  • 작업을 가져와서 작업자 고루틴으로 보냅니다.
  • 작업자 고루틴이 처리할 수 있는 것보다 더 많은 작업이 있고 버퍼링된 채널이 가득 차면 관리자 고루틴이 작업을 삭제합니다.


  • 예시



    드롭 패턴에서는 하루에 할 수 있는 작업량( capacity )이 제한되어 있습니다.

    작업을 수행할 employees의 사전 정의된 수(worker 고루틴)가 있습니다.

    또한 작업을 생성하는(또는 미리 정의된 작업 목록에서 작업을 가져오는) manager( main goroutine)도 있습니다.
    Manager은 통신 채널 ch을 통해 직원에게 작업에 대해 알립니다. Employee 은 통신 채널 ch 에서 작업을 가져옵니다.

    통신 채널 ch은 제한된 양의 작업을 "대기열에"보관할 수 있습니다( buffered channel ). 우리는 채널이 제한된 capacity 을 가지고 있다고 말합니다. 채널 ch 이 가득 차면 manager 은 새 작업을 보낼 수 없으며 대신 해당 작업 단위를 삭제하기로 결정하고 새 작업 단위를 채널로 보내려고 시도합니다(이번에는 ch 에 약간의 공간이 있을 수 있음). Manager은 할 일이 있는 한 그렇게 할 것입니다.

    사용 사례



    이 패턴의 좋은 사용 사례는 DNS 서버입니다. DNS 서버는 제한된 용량 또는 주어진 순간에 처리할 수 있는 요청의 양이 제한되어 있습니다. DNS 서버에 더 많은 요청이 전송되면 서버에 과부하가 걸리거나 종료되거나 DNS 서버가 요청을 처리할 수 있을 때까지 새 요청을 DROP하도록 결정할 수 있습니다.

    Go Playground에서 예제를 자유롭게 시도하십시오.

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        // capacity
        // max number of active requests at any given moment
        const cap = 100
    
        // buffered channel is used to determine when we are at capacity
        ch := make(chan string, cap)
    
        // a worker goroutine
        // e.g. an employee
        go func() {
            // for-range loop used to check for new work on communication channel `ch`
            for p := range ch {
                fmt.Println("employee : received signal :", p)
            }
        }()
    
        // amount of work to do
        const work = 200
    
        // range over collection of work, one value at the time
        for w := 0; w < work; w++ {
            // select-case allow us to perform multiple channel operations
            // at the same time, on the same goroutine
            select {
    
            // signal/send work into channel
            // start getting goroutines busy doing work
            // e.g. manager sends work to employee via buffered communication channel
            //      if buffer is full, default case is executed
            case ch <- "paper":
                fmt.Println("manager : sent signal :", w)
    
            // if channel buffer is full, drop the message
            // allow us to detect that we are at capacity
            // e.g. manager drops the unit of work
            default:
                fmt.Println("manager : dropper data :", w)
            }
        }
    
        // once last piece of work is submitted, close the channel
        // worker goroutines will process everything from the buffer
        close(ch)
        fmt.Println("manager : sent shutdown signal")
    
        time.Sleep(time.Second)
    }
    


    결과




    go run main.go
    
    manager : sent signal : 0
    manager : sent signal : 1
    manager : sent signal : 2
    manager : sent signal : 3
    manager : sent signal : 4
    ...
    manager : dropper data : 101
    manager : dropper data : 102
    ...
    employee : received signal : paper
    employee : received signal : paper
    ...
    employee 0 : received shutdown signal
    ...
    employee : received signal : paper
    employee : received signal : paper
    


    결론



    이 기사에서는 드롭 채널 패턴에 대해 설명했습니다. 또한 간단한 구현 및 사용 사례를 제공했습니다.

    독자는 우수한 Ardan Labs 교육 자료를 확인하여 자세히 알아보시기 바랍니다.

    자원:
  • Ardan Labs
  • Cover image by Igor Mashkov from Pexels
  • Fan out picture
  • 좋은 웹페이지 즐겨찾기