{"id":4852,"date":"2018-03-19T11:50:44","date_gmt":"2018-03-19T18:50:44","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4852"},"modified":"2025-06-13T21:20:32","modified_gmt":"2025-06-14T04:20:32","slug":"timed-tasks-using-couchbase-go","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/timed-tasks-using-couchbase-go\/","title":{"rendered":"Tarefas cronometradas usando Couchbase e Go"},"content":{"rendered":"<h5>Alberto Marchetti \u00e9 um desenvolvedor full-stack e autor de<a href=\"https:\/\/hydex11.net\/renderscript_parallel_computing_on_android_the_easy_way\" target=\"_blank\" rel=\"noopener noreferrer\">\u00a0\"<\/a><a href=\"https:\/\/hydex11.net\/renderscript_parallel_computing_on_android_the_easy_way\" target=\"_blank\" rel=\"noopener noreferrer\">RenderScript: computa\u00e7\u00e3o paralela no Android, de maneira f\u00e1cil<\/a>.\" Ele est\u00e1 sempre vivendo no limite, mergulhando constantemente na descoberta de idiomas e tecnologias modernas.<\/h5>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-4851\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/03\/photo5834550288516754817-1024x1024.jpg\" alt=\"\" width=\"396\" height=\"396\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817-1024x1024.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817-300x300.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817-150x150.jpg 150w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817-768x768.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817-65x65.jpg 65w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817-50x50.jpg 50w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817-20x20.jpg 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/03\/photo5834550288516754817.jpg 1280w\" sizes=\"auto, (max-width: 396px) 100vw, 396px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Tarefas cronometradas<strong>\u00a0usando Couchbase e Go<\/strong><\/h2>\n<p>Nesta postagem, mostrarei como voc\u00ea pode explorar o sistema de indexa\u00e7\u00e3o do Couchbase para criar um sistema distribu\u00eddo de tarefas cronometradas. O c\u00f3digo de exemplo do projeto, juntamente com suas instru\u00e7\u00f5es de execu\u00e7\u00e3o, pode ser encontrado em <a href=\"https:\/\/github.com\/cmaster11\/cb-blog-timed-tasks\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/cmaster11\/cb-blog-timed-tasks<\/a>.<br \/>\n<em>Isen\u00e7\u00e3o de responsabilidade: devido \u00e0 complexidade do t\u00f3pico, apenas os trechos de c\u00f3digo relevantes s\u00e3o publicados nesta p\u00e1gina.<\/em><\/p>\n<h2><strong>O conceito<\/strong><\/h2>\n<p>Vamos tentar definir os requisitos desse sistema:<\/p>\n<ul>\n<li>O principal recurso de um sistema de tarefas cronometradas \u00e9 poder especificar quando uma determinada tarefa ser\u00e1 executada no tempo. Isso pode ser feito com o uso de um campo ExecuteAt, que conter\u00e1 o tempo de execu\u00e7\u00e3o desejado (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Unix_time\" target=\"_blank\" rel=\"noopener noreferrer\">Hora do Unix<\/a>com base em milissegundos).<\/li>\n<li>Um requisito moderno de software \u00e9 que ele deve suportar um ambiente com v\u00e1rios n\u00f3s, o que significa que precisa ser um sistema distribu\u00eddo. Devemos ent\u00e3o garantir que v\u00e1rios workers N\u00c3O processem as mesmas tarefas! Podemos usar um recurso interessante do Couchbase aqui, <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/optimistic-or-pessimistic-locking-which-one-should-you-pick\/\">bloqueio pessimista<\/a>que permitir\u00e1 que um funcion\u00e1rio busque um documento e o bloqueie, de modo que nenhum outro funcion\u00e1rio possa process\u00e1-lo.<\/li>\n<\/ul>\n<p>A seguir, uma poss\u00edvel estrutura para representar nossa tarefa:<\/p>\n<pre class=\"lang:default decode:true\">type Task struct {\r\n    Id string\r\n\r\n    \/\/ The desired task execution time\r\n    ExecuteAt int64\r\n\r\n    \/\/ Task-specific content\r\n    Content string\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h2><strong>Recursos do Couchbase<\/strong><\/h2>\n<p>Primeiro, aqui est\u00e1 uma vis\u00e3o geral dos recursos do Couchbase que usaremos:<\/p>\n<h3>META()<\/h3>\n<p>Cada documento em um bucket do Couchbase tem um documento META()associado, que cont\u00e9m informa\u00e7\u00f5es espec\u00edficas da entidade do documento, como:<\/p>\n<ul>\n<li>id - a chave do documento dentro do bucket.<\/li>\n<li>cas - um n\u00famero int64, usado pelo Couchbase para evitar <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/5.1\/sdk\/concurrent-mutations-cluster.html\" target=\"_blank\" rel=\"noopener noreferrer\">condi\u00e7\u00f5es da corrida<\/a>\u00a0durante a edi\u00e7\u00e3o de documentos.<\/li>\n<li>expira\u00e7\u00e3o - quando um documento deve expirar, ou 0 se ele nunca expirar.<\/li>\n<\/ul>\n<p><em>Dica<\/em>: Esses campos (por exemplo, META().cas) <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/5.1\/n1ql\/n1ql-language-reference\/indexing-meta-info.html\" target=\"_blank\" rel=\"noopener noreferrer\">pode ser indexado<\/a>\u00a0(a partir do Couchbase 5.0).<\/p>\n<h3><strong>CAS (Check and Set)<\/strong><\/h3>\n<p>Ao buscar um documento, seu valor CAS tamb\u00e9m \u00e9 retornado, e as chamadas subsequentes para alterar o documento podem especificar esse valor para garantir que editar\u00e3o a vers\u00e3o desejada do documento.<\/p>\n<p>Exemplo:<\/p>\n<ul>\n<li>O cliente A busca um documento e seu valor CAS atual \u00e9 1234.<\/li>\n<li>O cliente B edita o documento, o que altera o valor CAS para 5678.<\/li>\n<\/ul>\n<ol>\n<li>Se A tentar editar o documento sem fornecer o valor CAS, a edi\u00e7\u00e3o ser\u00e1 bem-sucedida, mas as altera\u00e7\u00f5es feitas por B ser\u00e3o perdidas.<\/li>\n<li>Se A tentar editar o documento fornecendo o valor CAS (1234), ser\u00e1 retornado um erro porque o valor atual (5678) \u00e9 diferente. O cliente A precisar\u00e1, ent\u00e3o, buscar o documento novamente e reexecutar o processo.<\/li>\n<\/ol>\n<p>O valor CAS \u00e9 uma ferramenta extremamente \u00fatil para garantir que n\u00e3o estamos substituindo ou alterando uma vers\u00e3o errada\/nova de um documento, perdendo suas altera\u00e7\u00f5es.<\/p>\n<h3><strong>Bloqueio pessimista<\/strong><\/h3>\n<p>O Couchbase nos permite \"bloquear\" um documento, de modo que ele s\u00f3 possa ser lido e gravado por um cliente de cada vez, usando <a href=\"https:\/\/github.com\/couchbase\/gocb\/blob\/v1.3.3\/bucket_crud.go#L18\" target=\"_blank\" rel=\"noopener noreferrer\">gocb.GetAndLock<\/a>\u00a0Fun\u00e7\u00e3o do Go SDK.<\/p>\n<pre class=\"lang:default decode:true\">\/\/ Lock the document\r\nlockTime := 10 \/\/ seconds\r\nlockedCAS, err := bucket.GetAndLock(documentKey, lockTime, &amp;outStruct)\r\n\r\n\/\/ Unlock it\r\n_, err = bucket.Unlock(documentKey, lockedCAS)<\/pre>\n<p>&nbsp;<\/p>\n<p>Quando um documento \u00e9 bloqueado, todas as outras solicita\u00e7\u00f5es de bloqueio\/muta\u00e7\u00e3o\/desbloqueio geram um erro (ainda \u00e9 poss\u00edvel simplesmente obter o documento), a menos que o valor CAS correto seja usado.<\/p>\n<p>Observa\u00e7\u00e3o: O tempo m\u00e1ximo de bloqueio de um documento \u00e9 de 15 segundos, e o uso de um valor de lockTime igual a 0 far\u00e1 com que o tempo m\u00e1ximo seja definido. Isso cria uma limita\u00e7\u00e3o de quanto tempo uma tarefa pode ser executada antes de ser automaticamente marcada como dispon\u00edvel (por tempo limite de bloqueio).<\/p>\n<p><em>Dica:<\/em>\u00a0Enquanto um documento estiver bloqueado, seu valor CAS retornado ser\u00e1 -1.<\/p>\n<h2><strong>Indexa\u00e7\u00e3o e consulta<\/strong><\/h2>\n<p>\u00c9 importante observar que as duas dicas juntas nos informam que podemos indexar um campo (META().cas), que passa a ser -1 quando um documento est\u00e1 bloqueado. Isso tamb\u00e9m significa que podemos consultar documentos com base nessa condi\u00e7\u00e3o!<\/p>\n<h3><strong>A consulta<\/strong><\/h3>\n<p>Vamos tentar definir uma consulta para atender aos requisitos:<\/p>\n<ul>\n<li>Queremos obter um ID de tarefa, que pode ser usado posteriormente para obter e bloquear o documento: SELECT Id.<\/li>\n<li>A tarefa n\u00e3o deve estar bloqueada: WHERE META().cas  -1.<\/li>\n<li>A tarefa precisa ser executada agora: WHERE ExecuteAt &lt;= NOW_MILLIS() (<a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/n1ql\/n1ql-language-reference\/datefun.html#story-h2-30\" target=\"_blank\" rel=\"noopener noreferrer\">NOW_MILLIS<\/a>\u00a0retorna a hora atual do Unix em milissegundos).<\/li>\n<li>Precisamos buscar a tarefa mais pr\u00f3xima no tempo, portanto, queremos classificar as tarefas por seu tempo de execu\u00e7\u00e3o: ORDER BY ExecuteAt ASC.<\/li>\n<li>Digamos, por enquanto (!!!), que um funcion\u00e1rio queira processar apenas uma tarefa por vez: LIMITE 1.<\/li>\n<\/ul>\n<p>O resultado deve ser semelhante a esta consulta:<\/p>\n<pre class=\"lang:default decode:true\">SELECT `Id`\r\nFROM `timed_tasks` \/\/ Our bucket\r\nWHERE META().`cas` &lt;&gt; -1\r\nAND `ExecuteAt` &lt;= NOW_MILLIS()\r\nORDER BY `ExecuteAt` ASC\r\nLIMIT 1<\/pre>\n<p>Sua execu\u00e7\u00e3o retornar\u00e1 uma matriz semelhante a:<\/p>\n<pre class=\"lang:default decode:true\">[{\r\n    \"Id\": \"task_id_goes_here\"\r\n}]<\/pre>\n<p>&nbsp;<\/p>\n<h3><strong>O \u00edndice<\/strong><\/h3>\n<p>Agora podemos planejar um \u00edndice espec\u00edfico da consulta, otimizado para a execu\u00e7\u00e3o da consulta que acabamos de pensar. Os \u00edndices espec\u00edficos da consulta s\u00e3o essenciais para melhorar o desempenho da consulta no banco de dados NoSQL.<\/p>\n<ul>\n<li>A consulta est\u00e1 verificando se um documento n\u00e3o est\u00e1 bloqueado no momento:\n<pre class=\"lang:default decode:true\">WHERE META().cas &lt;&gt; -1.<\/pre>\n<\/li>\n<li>Al\u00e9m disso, ele est\u00e1 solicitando diretamente que o tempo de execu\u00e7\u00e3o esteja no passado. Em seguida, precisamos indexar o campo ExecuteAt.<br \/>\nA consulta de \u00edndice poderia ser a seguinte:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">CREATE INDEX `idx_timed_task`\r\nON `timed_tasks`\r\n(`ExecuteAt` ASC)\r\nWHERE META().`cas` &lt;&gt; -1<\/pre>\n<p>&nbsp;<\/p>\n<h3><strong>Otimiza\u00e7\u00e3o da consulta<\/strong><\/h3>\n<p>Agora podemos otimizar ainda mais a consulta:<\/p>\n<ul>\n<li>Podemos dizer \u00e0 consulta para usar nosso \u00edndice fornecendo um <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/5.1\/n1ql\/n1ql-language-reference\/hints.html\" target=\"_blank\" rel=\"noopener noreferrer\">dica<\/a>\u00a0a ele: USE INDEX (idx_timed_task USING GSI).<\/li>\n<li>Podemos pedir ao Couchbase que aguarde a atualiza\u00e7\u00e3o do \u00edndice (geralmente a indexa\u00e7\u00e3o \u00e9 um processo ass\u00edncrono) antes de executar a consulta, para que nossos resultados contenham, com certeza, tarefas desbloqueadas, fornecendo um <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/5.1\/indexes\/performance-consistency.html\" target=\"_blank\" rel=\"noopener noreferrer\">consist\u00eancia<\/a>\u00a0requisito no n\u00edvel do SDK: query.Consistency(gocb.RequestPlus).<\/li>\n<\/ul>\n<h2><strong>O fluxo<\/strong><\/h2>\n<p>Um fluxo poss\u00edvel para o loop de trabalho do consumidor da tarefa cronometrada \u00e9:<\/p>\n<ol>\n<li>Consulta de um ID de tarefa dispon\u00edvel.<\/li>\n<li>Obtenha e bloqueie a tarefa.<\/li>\n<li>Processar a tarefa.<\/li>\n<li>Excluir a tarefa.<\/li>\n<\/ol>\n<h3><strong>V\u00e1rios n\u00f3s<\/strong><\/h3>\n<p>Vamos pensar um pouco sobre como uma configura\u00e7\u00e3o de v\u00e1rios n\u00f3s pode alterar esse fluxo.<\/p>\n<p>Se v\u00e1rios funcion\u00e1rios forem consultar as tarefas dispon\u00edveis simultaneamente, eles provavelmente encontrar\u00e3o a mesma tarefa e apenas um deles poder\u00e1 process\u00e1-la com \u00eaxito, enquanto os outros funcion\u00e1rios ter\u00e3o que repetir o loop (executar uma nova consulta) para obter novas tarefas.<\/p>\n<p>Ent\u00e3o, podemos implementar outra abordagem:<\/p>\n<ol>\n<li>Consulta de ids de tarefas dispon\u00edveis, limitando a quantidade de ids ao n\u00famero de trabalhadores.<\/li>\n<li>Para cada ID de tarefa, tente bloquear a tarefa. No primeiro bloqueio bem-sucedido, v\u00e1 para 4.<\/li>\n<li>Se nenhuma tarefa tiver sido bloqueada com \u00eaxito, repita o loop.<\/li>\n<li>Processar a tarefa.<\/li>\n<li>Excluir a tarefa.<\/li>\n<\/ol>\n<p>Na melhor das hip\u00f3teses, cada trabalhador conseguir\u00e1 bloquear uma tarefa com sucesso na primeira tentativa. Na pior das hip\u00f3teses, os trabalhadores precisar\u00e3o tentar bloquear v\u00e1rios documentos sem sucesso. Em uma execu\u00e7\u00e3o m\u00e9dia, os funcion\u00e1rios bloquear\u00e3o as tarefas com \u00eaxito, talvez depois de tentar bloquear algumas outras.<\/p>\n<p>Temos que estabelecer um compromisso entre a frequ\u00eancia com que queremos consultar o banco de dados e o n\u00famero de tentativas de bloqueio com falha que podemos suportar. De modo geral, tentar bloquear documentos ser\u00e1 muito mais r\u00e1pido do que executar consultas N1QL.<\/p>\n<h2><strong>O c\u00f3digo<\/strong><\/h2>\n<p>Vamos dar uma olhada em alguns exemplos de c\u00f3digo relevantes:<\/p>\n<h3><strong>O produtor<\/strong><\/h3>\n<p>A gera\u00e7\u00e3o da tarefa pode ser resumida nessa fun\u00e7\u00e3o:<\/p>\n<pre class=\"lang:default decode:true\">func NewTask(executeAt time.Time, content string) (*Task, error) {\r\n    if executeAt.IsZero() {\r\n        return nil, errors.New(\"executeAt must not be a zero time\")\r\n    }\r\n\r\n    taskUUID, err := uuid.NewV1() \/\/ github.com\/satori\/go.uuid\r\n    if err != nil {\r\n        return nil, err\r\n    }\r\n\r\n    \/\/ Convert time.Time to int64 milliseconds\r\n    executeAtMillis := executeAt.UnixNano() \/ int64(time.Millisecond)\r\n\r\n    task := Task{\r\n        Id:        taskUUID.String(),\r\n        ExecuteAt: executeAtMillis,\r\n        Content:   content,\r\n    }\r\n\r\n    return &amp;task, nil\r\n}\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Depois de gerarmos um objeto de tarefa v\u00e1lido, podemos simplesmente inseri-lo em nosso bucket com:<\/p>\n<pre class=\"lang:default decode:true\">_, err := controller.bucket.Insert(task.Id, task, 0)<\/pre>\n<p>&nbsp;<\/p>\n<h3><strong>O consumidor<\/strong><\/h3>\n<p>Podemos obter e bloquear um documento por id, usando este c\u00f3digo:<\/p>\n<pre class=\"lang:default decode:true\">\/\/ Using zero values for lock time will set the maximum time available.\r\ntask := new(Task)\r\nlockedCAS, err := controller.bucket.GetAndLock(taskId, 0, &amp;task)<\/pre>\n<p>Uma tarefa pode ser removida usando esse c\u00f3digo:<\/p>\n<pre class=\"lang:default decode:true\">_, err := controller.bucket.Remove(taskId, lockedCAS)<\/pre>\n<p>O c\u00f3digo principal do consumidor pode ser resumido com o seguinte trecho:<\/p>\n<pre class=\"lang:default decode:true\">taskIds, err := couchbaseController.QueryNextTaskIds(consumersCount)\r\n...\r\n\r\nif len(taskIds) == 0 {\r\n    ...\r\n    \/\/ No tasks have been found, restart the loop\r\n}\r\n\r\nvar taskId string\r\nvar task *internal.Task\r\nvar lockedCAS gocb.Cas\r\n\r\nfor _, taskId = range taskIds {\r\n    \/\/ Lock and get the task, so that only this consumer will process it\r\n    task, lockedCAS, err = couchbaseController.GetAndLockTask(taskId)\r\n    if err != nil {\r\n        ...\r\n        \/\/ Error getting the task, proceed to next one in list\r\n        continue\r\n    }\r\n\r\n    \/\/ Successfully locked task!\r\n    \/\/ Move out to process it\r\n    break\r\n}\r\n\r\nif task == nil {\r\n    ...\r\n    \/\/ No tasks could be locked, restart loop\r\n}\r\n\r\n\/\/ Actual processing of the task\r\n\/\/ Improvement: could also return an error, which would let the task be\r\n\/\/ processed by another worker later.\r\nprocessTask(task)\r\n\r\n\/*\r\nRemove the task from Couchbase.\r\nThe task will be currently locked, which means we need to provide the\r\ncurrent CAS value, so that the producer is authorized to remove it.\r\n *\/\r\nerr = couchbaseController.RemoveTask(taskId, lockedCAS)\r\n...\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h2><strong>Conclus\u00e3o<\/strong><\/h2>\n<p>Nesta postagem, vimos uma maneira de criar um sistema confi\u00e1vel de tarefas cronometradas distribu\u00eddas usando Couchbase e Go.<\/p>\n<p>Esse sistema pode ser desenvolvido ainda mais:<\/p>\n<ul>\n<li>Suporte a erros de processamento.<\/li>\n<li>Implementa\u00e7\u00e3o de um recurso de repeti\u00e7\u00e3o (se o processamento falhar, reprogramar a tarefa no futuro).<\/li>\n<li>Aprimorar a l\u00f3gica de bloqueio:\n<ul>\n<li>Ajuste do n\u00famero m\u00e1ximo de IDs de tarefas retornados (em vez da contagem padr\u00e3o de trabalhadores).<\/li>\n<li>Suporte a uma dura\u00e7\u00e3o de processamento de tarefa de mais de 15 segundos (o tempo m\u00e1ximo de bloqueio de um documento no Couchbase).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Obrigado por seu tempo e feliz desenvolvimento!<\/p>\n<p style=\"text-align: center\"><em>Esta postagem faz parte do <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/community\/community-writers-program\/\" target=\"_blank\" rel=\"noopener noreferrer\">Programa de reda\u00e7\u00e3o comunit\u00e1ria<\/a><\/em><\/p>","protected":false},"excerpt":{"rendered":"<p>Alberto Marchetti is a full-stack developer, and author of\u00a0\u201cRenderScript: parallel computing on Android, the easy way.\u201d\u00a0He is always living on the edge by constantly jumping into the discovery of modern languages and technologies. &nbsp; Timed tasks\u00a0using Couchbase and Go In [&hellip;]<\/p>","protected":false},"author":53,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,1820],"tags":[],"ppma_author":[9026],"class_list":["post-4852","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-golang"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Timed tasks using Couchbase and Go - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"See how to use the Couchbase indexing system to create a timed-tasks distributed system using Couchbase and Go. Also, check some Couchbase features.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/timed-tasks-using-couchbase-go\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Timed tasks using Couchbase and Go\" \/>\n<meta property=\"og:description\" content=\"See how to use the Couchbase indexing system to create a timed-tasks distributed system using Couchbase and Go. Also, check some Couchbase features.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/timed-tasks-using-couchbase-go\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-03-19T18:50:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T04:20:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/06\/CB-Blog_red-black-big.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/06\/CB-Blog_red-black-big.png\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/\"},\"author\":{\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\"},\"headline\":\"Timed tasks using Couchbase and Go\",\"datePublished\":\"2018-03-19T18:50:44+00:00\",\"dateModified\":\"2025-06-14T04:20:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/\"},\"wordCount\":1311,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Couchbase Server\",\"GoLang\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/\",\"name\":\"Timed tasks using Couchbase and Go - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2018-03-19T18:50:44+00:00\",\"dateModified\":\"2025-06-14T04:20:32+00:00\",\"description\":\"See how to use the Couchbase indexing system to create a timed-tasks distributed system using Couchbase and Go. Also, check some Couchbase features.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Timed tasks using Couchbase and Go\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\",\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"caption\":\"Laura Czajkowski, Developer Community Manager, Couchbase\"},\"description\":\"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/laura-czajkowski\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Timed tasks using Couchbase and Go - The Couchbase Blog","description":"Veja como usar o sistema de indexa\u00e7\u00e3o do Couchbase para criar um sistema distribu\u00eddo de tarefas cronometradas usando o Couchbase e Go. Al\u00e9m disso, confira alguns recursos do Couchbase.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/timed-tasks-using-couchbase-go\/","og_locale":"pt_BR","og_type":"article","og_title":"Timed tasks using Couchbase and Go","og_description":"See how to use the Couchbase indexing system to create a timed-tasks distributed system using Couchbase and Go. Also, check some Couchbase features.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/timed-tasks-using-couchbase-go\/","og_site_name":"The Couchbase Blog","article_published_time":"2018-03-19T18:50:44+00:00","article_modified_time":"2025-06-14T04:20:32+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/06\/CB-Blog_red-black-big.png","type":"image\/png"}],"author":"Laura Czajkowski, Developer Community Manager, Couchbase","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/06\/CB-Blog_red-black-big.png","twitter_misc":{"Written by":"Laura Czajkowski, Developer Community Manager, Couchbase","Est. reading time":"6 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/"},"author":{"name":"Laura Czajkowski, Developer Community Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220"},"headline":"Timed tasks using Couchbase and Go","datePublished":"2018-03-19T18:50:44+00:00","dateModified":"2025-06-14T04:20:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/"},"wordCount":1311,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Couchbase Server","GoLang"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/","url":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/","name":"Timed tasks using Couchbase and Go - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2018-03-19T18:50:44+00:00","dateModified":"2025-06-14T04:20:32+00:00","description":"Veja como usar o sistema de indexa\u00e7\u00e3o do Couchbase para criar um sistema distribu\u00eddo de tarefas cronometradas usando o Couchbase e Go. Al\u00e9m disso, confira alguns recursos do Couchbase.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/timed-tasks-using-couchbase-go\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Timed tasks using Couchbase and Go"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220","name":"Laura Czajkowski, gerente da comunidade de desenvolvedores, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409","url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","caption":"Laura Czajkowski, Developer Community Manager, Couchbase"},"description":"Laura Czajkowski \u00e9 a Snr. Developer Community Manager da Couchbase, supervisionando a comunidade. Ela \u00e9 respons\u00e1vel pelo nosso boletim informativo mensal para desenvolvedores.","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/laura-czajkowski\/"}]}},"authors":[{"term_id":9026,"user_id":53,"is_guest":0,"slug":"laura-czajkowski","display_name":"Laura Czajkowski, Developer Community Manager, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","author_category":"","last_name":"Czajkowski","first_name":"Laura","job_title":"","user_url":"","description":"Laura Czajkowski \u00e9 a Snr. Developer Community Manager da Couchbase, supervisionando a comunidade. Ela \u00e9 respons\u00e1vel pelo nosso boletim informativo mensal para desenvolvedores."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4852","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=4852"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4852\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=4852"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=4852"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=4852"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=4852"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}