• Как написать программу на СИ?

    @nakem
    Если без указателей, то можно передать в check_word(char *words, int i, char *target). А в самой функции перемещаться по индексу
  • Как понять причину отмененного контекста?

    @nakem Автор вопроса
    Вы снова правы! Проблема сдвинулась с мертвой точки. В processIncomingAudioChunks() подается канал, который должен заполниться аудио, которое передастся в denoise(). Этот канал был небуферизированный, я добавил буфер 1, и тест прошел, контекст не отменился. Если честно, я не могу понять почему так происходит.
    Я написал еще один тест уже с нормальным 5 мегабайтным ваф файлом. Там такая же ошибка.

    processIncomingAudioChunks() приложил. Там с небуферизированным каналом все никак не хотелось выполнятся селект
    case audio <- audioChunk[:n]
    . Вроде с другой стороны в mock все ждут.
    А вот processBackendResponses()
    func (h *Handler) processBackendResponses(ctx context.Context, w http.ResponseWriter, responsesCh <-chan *denoiser.Response,
    ) error {
    	var (
    		resp           *denoiser.Response
    		ok             bool
    		firstBytesSent bool
    	)
    	flusher, _ := w.(http.Flusher)
    	for {
    		select {
    		case <-ctx.Done():
    			return ctx.Err()
    		case resp, ok = <-responsesCh:
    			if !ok {
    				// h.logger.Info(ctx, "Finished request successfully")
    				// h.metrics.SuccessfulRequests.With(h.metricLabels).Inc()
    				return nil
    			}
    			if resp.Err != nil {
    				return resp.Err
    			}
    			if resp.Audio != nil {
    				if !firstBytesSent {
    					firstBytesSent = true
    					w.Header().Set(headerContentType, contentTypeWAV)
    				}
    				if err := contextutil.DoWithTimeout(ctx, func() error {
    					_, err := w.Write(resp.Audio)
    					return err
    				}, h.cfg.WriteTimeout.ToNative()); err != nil {
    					h.logger.Warne(ctx, "Could not write response", err)
    					h.metrics.InternalErrors.With(h.metricLabels).Inc()
    					return err
    				}
    				flusher.Flush()
    			}
    		}
    	}
    }


    Вот автосгенерированный mock
    func (_m *mockDenoiser) Denoise(ctx context.Context, request *denoiser.Request, reqData <-chan []byte) <-chan *denoiser.Response {
    	ret := _m.Called(ctx, request, reqData)
    
    	var r0 <-chan *denoiser.Response
    	if rf, ok := ret.Get(0).(func(context.Context, *denoiser.Request, <-chan []byte) <-chan *denoiser.Response); ok {
    		r0 = rf(ctx, request, reqData)
    	} else {
    		if ret.Get(0) != nil {
    			r0 = ret.Get(0).(<-chan *denoiser.Response)
    		}
    	}
    
    	return r0
    }
  • Как сделать нормальное выключение Websocket сервера?

    @nakem Автор вопроса
    Евгений Мамонов, я пишу небольшой пакет для работы с вебсокет сервером. У меня нет доступа к внутренней логике. Закрытие происходит сейчас так:
    выключаю http сервер для ограничения подключения новых соединений -> вейтгруппой жду пока все хендлеры закончат работу, то есть либо клиент отправит фрейм о закрытии, либо сервер.
    Но в таком случае если клиент отключится без отправки фрейма, то соединение будет висеть, если сервер не будет сам что-то отправлять. Я решил постоянно отправлять фрейм пинг и ждать понг. Если понг не придет в установленный срок, то соединение закрывается со стороны сервера.