Nimlang: программа Asyn c не компилируется - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь написать HTTP-сервер, который отправляет HTTP-запрос и возвращает содержимое клиенту.

Вот код:

import asynchttpserver, asyncdispatch
import httpClient

let client = newHttpClient()

var server = newAsyncHttpServer()

proc cb(req: Request) {.async.} =

  let content = client.getContent("http://google.com")
  await req.respond(Http200, content)

waitFor server.serve(Port(8080), cb)

Однако я получаю следующее сообщение об ошибке компиляции (nim v1.0.0):

Error: type mismatch: got <AsyncHttpServer, Port, proc (req: Request): Future[system.void]{.locks: <unknown>.}>
but expected one of:
proc serve(server: AsyncHttpServer; port: Port;
          callback: proc (request: Request): Future[void] {.closure, gcsafe.};
          address = ""): owned(Future[void])
  first type mismatch at position: 3
  required type for callback: proc (request: Request): Future[system.void]{.closure, gcsafe.}
  but expression 'cb' is of type: proc (req: Request): Future[system.void]{.locks: <unknown>.}
  This expression is not GC-safe. Annotate the proc with {.gcsafe.} to get extended error information.

expression: serve(server, Port(8080), cb)

Функция serve ожидает другое выражение, но не знает, как его исправить. Удивительно, но код прекрасно компилируется, когда я удаляю HTTP-запрос из обратного вызова сервера «cb». Означает ли это, что функция serve ожидает различные выражения обратного вызова в зависимости от тела обратного вызова?

1 Ответ

1 голос
/ 08 марта 2020

ОК, проблема в том, что HttpClient является глобальной переменной и используется в функции обратного вызова "cb". В результате функция обратного вызова не является безопасной G C.

Так что достаточно создать экземпляр HttpClient в функции обратного вызова:

import asynchttpserver, asyncdispatch
import httpClient



var server = newAsyncHttpServer()

proc cb(req: Request) {.async.} =

  let client = newHttpClient()

  let content = client.getContent("https://google.com")

  await req.respond(Http200, content)

waitFor server.serve(Port(8080), cb)
...