cuducos / minha-receita

🏢 Sua API web para consulta de informações do CNPJ da Receita Federal

Home Page:https://minhareceita.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`panic: send on closed channel` quando rodando o ETL com dados de 2023-01

cuducos opened this issue · comments

$ minha-receita download
# 

$ minha-receita transform -c
2023/02/04 01:37:22 Dropping table public.cnpj…
2023/02/04 01:37:22 Creating table public.cnpj…
2023/02/04 01:37:22 Saving the updated at date to the database…
2023/02/04 01:37:22 Loading Simples files…
2023/02/04 01:37:22 Loading Socios files…
2023/02/04 01:37:22 Loading Empresas files…
Processing base CNPJ, partners and taxes 100% |████████████████████████████████████████████████████████████████████████████████████| (108762489/108762489, 29588 it/s)             
2023/02/04 02:38:50 Loading Estabelecimentos files…                                                                                                                                
Creating the JSON data for each CNPJ 100% |███████████████████████████████████████████████████████████████████████████████████████████| (22888448/55155262, 13816 it/s)            
panic: send on closed channel

goroutine 82738092 [running]:
github.com/cuducos/minha-receita/transform.(*venuesTask).consumeRows(0xc00017a0a0)
	/Users/cuducos/Dropbox/Projects/minha-receita/transform/venues.go:92 +0x308
created by github.com/cuducos/minha-receita/transform.(*venuesTask).run
	/Users/cuducos/Dropbox/Projects/minha-receita/transform/venues.go:125 +0x18b
panic: send on closed channel

goroutine 82738088 [running]:
github.com/cuducos/minha-receita/transform.(*venuesTask).consumeRows(0xc00017a0a0)
	/Users/cuducos/Dropbox/Projects/minha-receita/transform/venues.go:92 +0x308
created by github.com/cuducos/minha-receita/transform.(*venuesTask).run
	/Users/cuducos/Dropbox/Projects/minha-receita/transform/venues.go:125 +0x18b

Os dados (essa versão) estão em mirror.minhareceita.org.

Quando eu rodo com o docker não vejo o stack trace e só aparece "erro ". Seria o mesmo? Como eu poderia visualizar esse stack trace (desculpas se a pergunta é meio lazy)?

➜  minha-receita git:(main) docker-compose run --rm minha-receita transform -d /mnt/data/ -x
Creating minha-receita_minha-receita_run ... done
2023/02/06 20:17:43 Saving the updated at date to the database…
2023/02/06 20:17:43 Loading Simples files…
2023/02/06 20:17:43 Loading Socios files…
2023/02/06 20:17:43 Loading Empresas files…
Processing base CNPJ, partners and taxes   0% |                                           | (936386/108762489, 6 it/s) [1m2s:4682h36m39s]ERROR: 137

E, claro, parabéns por esse projeto incrível!

Olha, que eu saiba, deveria aprecer igual, mas faz tempo que não rodo utilizando o Docker, pode ser que ele trate stdout e stderr de forma diferente. Vou testar mais tarde aqui e atualizo aqui.

Boa, valeu! Um update: acabei de instalar local e executar os mesmos comandos. Ainda está em 4% mas já passou do ponto onde dava erro (em torno de 1%). Se quiser posso criar uma outra issue pra esse problema porque parece diferente. Agora estou testando com os dados do final de dezembro, inclusive, porque queria eliminar a possibilidade de ser algo na última base.

Agora estou testando com os dados do final de dezembro, inclusive, porque queria eliminar a possibilidade de ser algo na última base.

Os dados de dezembro funcionam (funcionaram?) pois é o que está em produção. Sempre bom testar.

Quando rodei aqui e abri a issue, testei em dois computadores diferentes (um macOS e um Linux) e sempre deu o erro que mencionei por volta dos 41% da segunda barra de rolagem (criando os registros no banco).

Eu desconfio, então, que seja algum problema na base atual, e isso a gente não pode arrumar. Mas… não era para dar panic: send on closed channel, era para mostrar uma mensagem de erro mais precisa…

Com o Docker não funcionou. Mas, local, parece estar está funcionando (35% agora). Tô rodando de um MacOs. Aviso quando tiver mais notícias.

Erro aparece com docker-compose aqui tb:

$ docker-compose run --rm minha-receita transform -c -d /mnt/data
2023/02/06 21:44:08 Dropping table public.cnpj…
2023/02/06 21:44:08 Creating table public.cnpj…
2023/02/06 21:44:08 Saving the updated at date to the database…
2023/02/06 21:44:09 Loading Simples files…
2023/02/06 21:44:09 Loading Empresas files…
2023/02/06 21:44:09 Loading Socios files…
Processing base CNPJ, partners and taxes  16% |█████████████                                                                     | (17485676/108762489, 44873 it/s) [6m42s:33m54s]aPProcessing base CNPJ, partners and taxes 100% |█████████████████████████████████████████████████████████████████████████████████████| (108762489/108762489, 30485 it/s)            
2023/02/06 22:44:05 Loading Estabelecimentos files…                                                                                                                                
Creating the JSON data for each CNPJ   0% |                                                                                         | (229376/55155262, 852 it/s) [9m43s:17h54m55s]iCreating the JSON data for each CNPJ 100% |███████████████████████████████████████████████████████████████████████████████████████████| (22675456/55155262, 752 it/s)              
panic: send on closed channel

goroutine 74265407 [running]:
github.com/cuducos/minha-receita/transform.(*venuesTask).consumeRows(0xc00029f400)
	/minha-receita/transform/venues.go:100 +0x3ab
created by github.com/cuducos/minha-receita/transform.(*venuesTask).run
	/minha-receita/transform/venues.go:125 +0x18b

Alguma novidade referente a esse erro?
Deu para mim quando rodei hoje no meu mac.

Aparentemente o bug ocorre dentro do Badger. Retirei todos os close(channel) do código para evitar o panic: send on closed channel e esse foi o resultado:

2023/03/23 08:24:34 Dropping table public.cnpj…
2023/03/23 08:24:40 Creating table public.cnpj…
2023/03/23 08:24:40 Saving the updated at date to the database…
2023/03/23 08:24:40 Loading Simples files…
2023/03/23 08:24:40 Loading Empresas files…
2023/03/23 08:24:40 Loading Socios files…
Processing base CNPJ, partners and taxes 100% |█████████████████████████████████████████| (109543959/109543959, 73981 it/s)            
2023/03/23 08:49:29 Loading Estabelecimentos files…                                                                                    
Creating the JSON data for each CNPJ 100% |████████████████████████████████████████████████| (47382528/55502948, 20780 it/s)           
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1824fcb]

goroutine 213844799 [running]:
github.com/dgraph-io/badger/v3.(*memTable).IncrRef(...)
	/Users/cuducos/go/pkg/mod/github.com/dgraph-io/badger/v3@v3.2103.4/memtable.go:231
github.com/dgraph-io/badger/v3.(*DB).getMemTables(0xc0005c0d80)
	/Users/cuducos/go/pkg/mod/github.com/dgraph-io/badger/v3@v3.2103.4/db.go:696 +0x12b
github.com/dgraph-io/badger/v3.(*DB).get(0xc0005c0d80, {0xc029629e48, 0x14, 0x14})
	/Users/cuducos/go/pkg/mod/github.com/dgraph-io/badger/v3@v3.2103.4/db.go:730 +0x9d
github.com/dgraph-io/badger/v3.(*Txn).Get(0xc000b3ac00, {0xc039e359d0, 0xc, 0x10})
	/Users/cuducos/go/pkg/mod/github.com/dgraph-io/badger/v3@v3.2103.4/txn.go:478 +0x2b5
github.com/cuducos/minha-receita/transform.baseOf.func1(0xc0005c0d80?)
	/Users/cuducos/Dropbox/Projects/minha-receita/transform/badger.go:47 +0xa5
github.com/dgraph-io/badger/v3.(*DB).View(0x1?, 0xc000206678)
	/Users/cuducos/go/pkg/mod/github.com/dgraph-io/badger/v3@v3.2103.4/txn.go:806 +0x9c
github.com/cuducos/minha-receita/transform.baseOf(0x0?, {0xc039e35950, 0x8})
	/Users/cuducos/projects/minha-receita/transform/badger.go:46 +0xc5
github.com/cuducos/minha-receita/transform.(*badgerStorage).enrichCompany.func2()
	/Users/cuducos/projects/minha-receita/transform/kv.go:125 +0x7b
created by github.com/cuducos/minha-receita/transform.(*badgerStorage).enrichCompany
	/Users/cuducos/projects/minha-receita/transform/kv.go:124 +0x1ea
exit status 2

@cuducos Segmentation violation é quando o código tenta cutucar uma memória que não é dele, não?
Será que a memória utilizada pelo go não está sendo insuficiente para o processamento?

Será que a memória utilizada pelo go não está sendo insuficiente para o processamento?

Sou péssimo em “monitorar” essas coisas mais baixo nível, mas acho que não seria o caso, pois:

  • O uso do Badger (banco de chave/valor) é em disco (claro que ele usa memória, mas o grosso do armazenamento vai pro disco)
  • Monitorei o processo com aplicativos como htop, glances e o Activity Monitor do macOS e em nenhum momento o uso de memória me pareceu “perigoso” (perto de 100%)

Isso são hipóteses válidas?

Meu palpite tem sido mais para o lado de alta concorrência na leitura do Badger, penso em implementar um semáforo limitando o número de consultas paralelas. Mas é só um chute que compartilho para ver ser se faz sentido hehehe…

Então, pode acontecer um segmentation fault mesmo sem uso excessivo de memória.
A grosso modo ele ocorre sempre que um trecho de código toca algum endereço da memória que não estava reservado para ele.
Isso pode acontecer por que o heap da máquina esgotou, porque tem pouca memória alocada para o go, ou mesmo porque algum trecho do código tentou acessar um endereço de memória não alocada pra ele (acho que este seria a hipótese mais provável), como um índice de array inexistente.

Não manjo absolutamente nada de Go, mas seu trace para nessa linha:
image

Talvez o problema esteja justamente nessa função baseOf.
Faz sentido?

PS.: Sobre a concorrência tbm faz sentido, alta concorrência também significa mais coisas acessando memória ao mesmo tempo, para alguma coisa bater onde não deve é rapidinho.

Talvez o problema esteja justamente nessa função baseOf.
Faz sentido?

Arrisco dizer que essa hipótese é fraca, pois a função baseOf funciona perfeitamente com os dados de até dezembro de 2022. O banco de dados de produção foi alimentado com ela desse jeito, sem tirar nem por, em dezembro.

Será que algum registro está fazendo ela retornar algo que não deveria?

Isso é uma hipótese que explorei um pouco, e inicialmente descartei. Os arquivos dos datasets originais são numerados de 0 a 9. Rodei individualmente: só os com final 0, funcionou; só os com final 1, funcionou; e assim por diante.

Mas… voltando a falar disso, vc me deu uma ideia: pode ser que não necessariamente os registros do Estabelecimento1 tem seus detalhes em Socios1 e Empresas1. Pode ser misturado.

Vou testar rodar Estabelecimento0 mais todos os do quadro societário e empresas. Depois o Estabelecimento1 e assim por diante!

E se jogar em log os registros que estão sendo processados, para conseguir ver qual exatamente estoura o erro?

Testei fazer isso na consulda ao Badger (que era meu chute há um tempo atrás), mas toda consulta pro badger falha. Vou tentar fazer isso salvando o dados que a gente joga pro Postgres tb!

Muito obrigado pelas ideias!

Opa... se eu conseguir ajudar em algo estou aqui para somar.

se eu conseguir ajudar em algo estou aqui para somar

Acho que tu conseguiu me ajudar com algo que eu e @alexandrasp estávamos tentando já tinha tempo: isolar minimamente o problema!

Com essa conversa, segui essa estratégia:

Vou testar rodar Estabelecimento0 mais todos os do quadro societário e empresas. Depois o Estabelecimento1 e assim por diante!

Aparentemente sempre trava no Estabelecimentos7 — vou tentar criar um pacote de dados mínimo para esses testes. Isolar só os CNPJs desse arquivo, e ir afunilando. Progresso, finalmente!

Ainda não consegui isolar mais, mas para reproduzir o erro aparentemente precisamos apenas desses dados. Vou focar em reduzir esses datasets ainda mais.

UPDATE

Após rodar o transform, esses CNPJs foram criados antes de travar. Acho que dá para tirar essas linhas do Estabelecimentos7.zip e isolar mais assim…

Estamos chegando perto. Nos logs do Postgres tem isso:

2023-04-12 17:01:30.181 EDT [13447] ERROR:  invalid input syntax for type json
2023-04-12 17:01:30.181 EDT [13447] DETAIL:  The input string ended unexpectedly.
2023-04-12 17:01:30.181 EDT [13447] CONTEXT:  JSON data, line 1: 
	COPY cnpj, line 1, column json
2023-04-12 17:01:30.181 EDT [13447] STATEMENT:  copy "cnpj" ( "id", "json" ) from stdin binary;

@cuducos Cara, eu dei uma olhada aqui no arquivo que vc colocou, eu fiz um scriptzinho em python para dar uma percorrida nele, achei alguns valores que não sei se deveriam estar assim:
image

Sei que o mais comum de vermos em cnpjs é um número com 14 dígitos, porém imagino que possa ter alguns menores que isso tbm (principalmente se for muito antigo), porém estes três últimos do print que anexei parecem não respeitar o formato padrão do cnpj (número + código de filial + dv)

Veja se faz sentido pra vc

Sei que o mais comum de vermos em cnpjs é um número com 14 dígitos

Para agilizar o índice no PostgreSQL os números do CNPJs são salvos como números inteiros (descarta zero à esquerda e converte para inteiro).

Em outras palavras, 8176, por exemplo, equivale ao CNPJ 00.000.000/0081-76 que é válido e existe:

image

Finalmente 🎉

error trying to parse DataSituacaoCadastral 1: error converting 2021221 to Time: parsing time "2021221": month out of range

Erro nos dados da Receita Federal que não estávamos capturando direito.

Ainda buscando uma solução…

Boa!

Parabéns!

Acabei de testar com a base de dados onde o erro começou e com a atual (abril/2023). Ambas funcionam. Atualizando o banco de dados de produção nas próximas horas. Sextou.

cc @carlosmixz @Ceagah e @LorhanSohaky — com quem mencionei esse bug em outras issues : )

Maravilhas!!!