Rodrigo Martins

I'm a Catholic Christian, software developer, Passionate about life, codes, questions, theories and theorems. :)

Resolvendo Problema Com $PORT Com Uma App Golang No Heroku

| Comments

Æ,

Já faz um tempo que venho estudando e praticando um pouco com Golang. Como alguns codigos estão somente em meu repo particular, resolvi colocar alguns de meus codígos em algum host para testes iniciais. Optei por usar o Heroku (não estou ganhando nada para fazer propaganda kkkkk).

Porém ao seguir o seu Getting Started with Go, percebi uma coisa: não deixam claro as politicas de porta de acesso à app.

Como resolver?

Não vou entrar nos detalhes para colocar a app no ar, pois o 'passo-a-passo'
do Heroku da uma boa ajuda quanto a isso.

Um dos packages nativos de Go, que é bem útil para usar no Heroku, é o package os.

A func que vamos usar aqui será a Getenv do pacote os, ela lê uma variavel de ambiente que é passada como parametro do tipo string.

e sua chamada será algo como:
1
  os.Getenv("")
A assinatura da func
1
  func Getenv(key string) string

Ok! Bora para o problema.

Sem a declaração desta chamada, para que a app possa saber qual será a porta que ela vai iniciar. Iremos observar nos logs do Heroku o seguinte erro:

A assinatura da func
1
2
  2015-09-28T21:57:58.411180+00:00 heroku[web.1]: Error R10 (Boot timeout) -> \
  Web process failed to bind to $PORT within 60 seconds of launch

Já se torna visivel que esta reclamando de algo com relação a variavel de ambiente $PORT, e por isso o processo web não foi iniciado, recebendo na cara um SIGKILL.

Ao ler a app de apresentação que foi publicada para ajuda pelo Heroku, app Go Getting Started on Github e ler mais afinco sobre este erro e sobre ‘o como o Heroku Apps precisa desta declaração :)’, saiu algo assim:

Declaração com a variavel de ambiente $PORT
1
  os.Getenv("PORT")

Lembrem, como estamos usando o pacote os, temos que fazer seu import.

Importando pacote os
1
   import "os"

Caso, não faça este import, verá um erro ao compilar o codigo, algo como:

Erro de compilação
1
2
3
4
$ go build
# heroku.com/rrmartins/rrtempo
./servidor.go:15: undefined: os
./servidor.go:16: undefined: os

Então, faça o import "os". :)

Sabendo a declaração, podemos iniciar o server:

Levantando o server
1
2
   port := os.Getenv("PORT")
   http.ListenAndServe(fmt.Sprintf(":%s", port),nil)

Na segunda linha do codígo acima, vemos mais dois pacotes nativos Go, http e fmt, para fazer funcionar é importante tambem fazer o import deles, ficando algo parecido com isso:

Importando mais pacotes
1
2
3
4
5
import (
  "fmt"
  "os"
  "net/http"
)

Mas, como o problema a ser resolvido não é ‘o como levantar o servidor’, mas sim ‘o que é preciso para tal’, então vamos voltar ao caso aqui. :)

Declarando só com port := os.Getenv("PORT"), é obrigatório que nas configurações da app no Heroku tenha a variavel $PORT declarada, e se não tiver? Quem poderá nos defender?

Para não fazer um if deste modo:

if desnecessario
1
2
3
4
5
  if os.Getenv("PORT") != "" {
    port = os.Getenv("PORT")
  } else {
    port = "8080"
  }

Fazemos uma condicional de uma linha só: :)

Condicional lindão
1
2
3
  port := map[bool]string{true: os.Getenv("PORT"), \
  false: "8080"}[ os.Getenv("PORT") != ""]
  http.ListenAndServe(fmt.Sprintf(":%s", port),nil)

Vejam só, se não tem a declaração da variavel $PORT, assumo a porta 8080.

É isso ai.

O codígo deste post esta em Github rrtime, e rodando no Heroku Heroku rrtime.

Creditos pela ajuda da condicional mais simples ao Vinicius Souza Twitter | Vinicius Souza Github contribuidor da comunidade brasileira Golang BR.

Valeu!

Comments