{"id":13783291,"url":"https://github.com/kafka4beam/brod","last_synced_at":"2025-05-13T19:13:42.117Z","repository":{"id":28036058,"uuid":"31531585","full_name":"kafka4beam/brod","owner":"kafka4beam","description":"Apache Kafka client library for Erlang/Elixir","archived":false,"fork":false,"pushed_at":"2025-05-08T15:18:45.000Z","size":3362,"stargazers_count":672,"open_issues_count":38,"forks_count":212,"subscribers_count":38,"default_branch":"master","last_synced_at":"2025-05-12T22:06:03.128Z","etag":null,"topics":["client","elixir","erlang","kafka","klarna-featured"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kafka4beam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-03-02T09:02:18.000Z","updated_at":"2025-05-08T15:18:49.000Z","dependencies_parsed_at":"2024-02-15T10:30:21.704Z","dependency_job_id":"e880c13f-9cd0-420e-a729-513ec4b4e4cf","html_url":"https://github.com/kafka4beam/brod","commit_stats":{"total_commits":949,"total_committers":90,"mean_commits":"10.544444444444444","dds":0.5247629083245522,"last_synced_commit":"c34fa870f00719fee6bc4cbff04f12121f08be6d"},"previous_names":[],"tags_count":124,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kafka4beam%2Fbrod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kafka4beam%2Fbrod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kafka4beam%2Fbrod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kafka4beam%2Fbrod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kafka4beam","download_url":"https://codeload.github.com/kafka4beam/brod/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254010813,"owners_count":21998995,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","elixir","erlang","kafka","klarna-featured"],"created_at":"2024-08-03T19:00:18.279Z","updated_at":"2025-05-13T19:13:42.085Z","avatar_url":"https://github.com/kafka4beam.png","language":"Erlang","funding_links":[],"categories":["Development","Erlang","Clients"],"sub_categories":["Client libraries","Elixir / Erlang"],"readme":"# NOTICE\n\nThis product includes software developed by\n[Klarna Bank AB (publ)](https://www.klarna.com)\n\n# Brod - Apache Kafka Client for Erlang/Elixir\n\n![brod](https://github.com/kafka4beam/brod/workflows/brod/badge.svg?branch=master)\n\nBrod is an Erlang implementation of the Apache Kafka protocol, providing support for both producers and consumers.\n\nWhy \"brod\"? [http://en.wikipedia.org/wiki/Max_Brod](http://en.wikipedia.org/wiki/Max_Brod)\n\n## Features\n\n- Supports Apache Kafka v0.8+\n- Robust producer implementation supporting in-flight requests and asynchronous acknowledgements\n- Both consumer and producer handle leader re-election and other cluster disturbances internally\n- Opens max 1 tcp connection to a broker per `brod_client`, one can create more clients if needed\n- Producer: will start to batch automatically when number of unacknowledged (in flight) requests exceeds configurable maximum\n- Producer: will try to re-send buffered messages on common errors like \"Not a leader for partition\", errors are resolved automatically by refreshing metadata\n- Simple consumer: The poller, has a configurable \"prefetch count\" - it will continue sending fetch requests as long as total number of unprocessed messages (not message-sets) is less than \"prefetch count\"\n- Group subscriber: Support for consumer groups with options to have Kafka as offset storage or a custom one\n- Topic subscriber: Subscribe on messages from all or selected topic partitions without using consumer groups\n- Pick latest supported version when sending requests to kafka.\n- Direct APIs for message send/fetch and cluster inspection/management without having to start clients/producers/consumers.\n- A escriptized command-line tool for message send/fetch and cluster inspection/management.\n- Configurable compression library. No compression is supported by default for both producers and consumers.\n  For more compression options, see [kafka_protocol/README](https://github.com/kafka4beam/kafka_protocol/blob/master/README.md#compression-support)\n\n## Building and testing\n\nNOTE: Min Erlang/OTP version 22\n\n```sh\nmake compile\nmake test-env t # requires docker-compose in place\n```\n\n## Working With Kafka 0.9.x or Earlier\n\nMake sure `{query_api_versions, false}` exists in client config.\nThis is because `ApiVersionRequest` was introduced in kafka 0.10,\nsending such request to older version brokers will cause connection failure.\n\ne.g. in `sys.config`:\n\n```erlang\n[{brod,\n   [ { clients\n     , [ { brod_client_1 %% registered name\n         , [ { endpoints, [{\"localhost\", 9092}]}\n           , { query_api_versions, false} %% \u003c---------- here\n           ]}]}]}]\n```\n\n## Quick Demo\n\nAssuming kafka is running at `localhost:9092` and there is a topic named `test-topic`.\n\nStart Erlang shell by `make compile; erl -pa _build/default/lib/*/ebin`, then paste lines below into shell:\n\n```erlang\nrr(brod),\n{ok, _} = application:ensure_all_started(brod),\nKafkaBootstrapEndpoints = [{\"localhost\", 9092}],\nTopic = \u003c\u003c\"test-topic\"\u003e\u003e,\nPartition = 0,\nok = brod:start_client(KafkaBootstrapEndpoints, client1),\nok = brod:start_producer(client1, Topic, _ProducerConfig = []),\n{ok, FirstOffset} = brod:produce_sync_offset(client1, Topic, Partition, \u003c\u003c\"key1\"\u003e\u003e, \u003c\u003c\"value1\"\u003e\u003e),\nok = brod:produce_sync(client1, Topic, Partition, \u003c\u003c\"key2\"\u003e\u003e, \u003c\u003c\"value2\"\u003e\u003e),\nSubscriberCallbackFun = fun(Partition, Msg, ShellPid = CallbackState) -\u003e ShellPid ! Msg, {ok, ack, CallbackState} end,\nReceive = fun() -\u003e receive Msg -\u003e Msg after 1000 -\u003e timeout end end,\nbrod_topic_subscriber:start_link(client1, Topic, Partitions=[Partition],\n                                 _ConsumerConfig=[{begin_offset, FirstOffset}],\n                                 _CommittedOffsets=[], message, SubscriberCallbackFun,\n                                 _CallbackState=self()),\nAckCb = fun(Partition, BaseOffset) -\u003e io:format(user, \"\\nProduced to partition ~p at base-offset ~p\\n\", [Partition, BaseOffset]) end,\nok = brod:produce_cb(client1, Topic, Partition, \u003c\u003c\u003e\u003e, [{\u003c\u003c\"key3\"\u003e\u003e, \u003c\u003c\"value3\"\u003e\u003e}], AckCb).\nReceive().\nReceive().\n{ok, {_, [Msg]}} = brod:fetch(KafkaBootstrapEndpoints, Topic, Partition, FirstOffset + 2), Msg.\n```\n\nExample outputs:\n\n```erlang\n#kafka_message{offset = 0,key = \u003c\u003c\"key1\"\u003e\u003e,\n               value = \u003c\u003c\"value1\"\u003e\u003e,ts_type = create,ts = 1531995555085,\n               headers = []}\n#kafka_message{offset = 1,key = \u003c\u003c\"key2\"\u003e\u003e,\n               value = \u003c\u003c\"value2\"\u003e\u003e,ts_type = create,ts = 1531995555107,\n               headers = []}\nProduced to partition 0 at base-offset 406\n#kafka_message{offset = 2,key = \u003c\u003c\"key3\"\u003e\u003e,\n               value = \u003c\u003c\"value3\"\u003e\u003e,ts_type = create,ts = 1531995555129,\n               headers = []}\n```\n\n## Overview\n\nBrod supervision (and process link) tree.\n\n![brod supervision architecture](https://cloud.githubusercontent.com/assets/164324/19621338/0b53ccbe-9890-11e6-9142-432a3a87bcc7.jpg)\n\n## Clients\n\nA `brod_client` in brod is a `gen_server` responsible for establishing and\nmaintaining tcp sockets connecting to kafka brokers.\nIt also manages per-topic-partition producer and consumer processes under\ntwo-level supervision trees.\n\nTo use producers or consumers, you have to start at least one client that\nwill manage them.\n\n### Compression\n\nBrod does not dependent on any compression/decompression implementation by default.\nTo enable them, you must add the compression application as dependency in your project's rebar.config.\n\nFor example:\n\n```erlang\n{deps, [\n    {snappyer, \"1.2.9\"}\n]}.\n```\n\n### Start clients by default\n\nYou may include client configs in `sys.config` have them started by default\n(by application controller)\n\nExample of configuration (for `sys.config`):\n\n```erlang\n[{brod,\n   [ { clients\n     , [ { brod_client_1 %% registered name\n         , [ { endpoints, [{\"localhost\", 9092}]}\n           , { reconnect_cool_down_seconds, 10} %% socket error recovery\n           ]\n         }\n       ]\n     }\n     %% start another client for another kafka cluster\n     %% or if you think it's necessary to start another set of tcp connections\n   ]\n}]\n```\n\nExample of configuration in Elixir (for `config/dev.exs` or `config/prod.exs`, etc.):\n\n```elixir\nconfig :brod,\n  clients: [\n    # :brod_client_1 is the registered name of the client\n    brod_client_1: [\n      endpoints: [{\"localhost\", 9092}],\n      reconnect_cool_down_seconds: 10\n    ]\n  ]\n```\n\n### Start brod client on demand\n\nYou may also call `brod:start_client/1,2,3` to start a client on demand,\nwhich will be added to brod supervision tree.\n\n```erlang\nClientConfig = [{reconnect_cool_down_seconds, 10}],\nok = brod:start_client([{\"localhost\", 9092}], brod_client_1, ClientConfig).\n```\n\nExtra [socket options](http://erlang.org/doc/man/gen_tcp.html#type-option)\ncould be passed as `{extra_sock_opts, ExtraSockOpts}`, e.g.\n\n```erlang\nExtraSockOpts = [{sndbuf, 1024*1024}],\nok = brod:start_client([{\"localhost\", 9092}], brod_client_1, [{extra_sock_opts, ExtraSockOpts}]).\n```\n\n## Producers\n\nA `brod_producer` is a `gen_server` that is responsible for producing messages to a given\npartition of a given topic.\n\nProducers may be started either manually or automatically in the moment you call `brod:produce`\nbut did not call `brod:start_producer` beforehand.\n\n### Auto start producer with default producer config\n\nPut below configs to client config in `sys.config` or app env if you start client statically:\n\n```erlang\n{auto_start_producers, true}\n{default_producer_config, []}\n```\n\nOr pass the `{auto_start_producers, true}` option to `brod:start_client` if you start the client\ndynamically.\n\n### Start a Producer on Demand\n\n```erlang\nbrod:start_producer(_Client         = brod_client_1,\n                    _Topic          = \u003c\u003c\"brod-test-topic-1\"\u003e\u003e,\n                    _ProducerConfig = []).\n```\n\n### Supported Message Input Format\n\nBrod supports below produce APIs:\n\n- [`brod:produce`](https://hexdocs.pm/brod/brod.html#produce/5): Async produce with ack message sent back to caller.\n- [`brod:produce_cb`](https://hexdocs.pm/brod/brod.html#produce_cb/6): Async produce with a callback evaluated when ack is received.\n- [`brod:produce_sync`](https://hexdocs.pm/brod/brod.html#produce_sync/5): Sync produce that returns `ok`.\n- [`brod:produce_sync_offset`](https://hexdocs.pm/brod/brod.html#produce_sync_offset/5): Sync produce that returns `{ok, BaseOffset}`.\n- [`brod:produce_no_ack`](https://hexdocs.pm/brod/brod.html#produce_no_ack/5): Async produce without backpressure (use with care!).\n\nThe `Value` arg in these APIs can be:\n\n- `binary()`: One single message\n- `{brod:msg_ts(), binary()}`: One single message with its create-time timestamp\n- `#{ts =\u003e brod:msg_ts(), value =\u003e binary(), headers =\u003e [{_, _}]}`:\n  One single message. If this map does not have a `key` field, the `Key` argument is used.\n- `[{K, V} | {T, K, V}]`: A batch, where `V` could be a nested list of such representation.\n- `[#{key =\u003e K, value =\u003e V, ts =\u003e T, headers =\u003e [{_, _}]}]`: A batch.\n\nWhen `Value` is a batch, the `Key` argument is only used as partitioner input and all messages are written on the same partition.\nAll messages are unified into a batch format of below spec:\n`[#{key =\u003e K, value =\u003e V, ts =\u003e T, headers =\u003e [{_, _}]}]`.\n`ts` field is dropped for kafka prior to version `0.10` (produce API version 0, magic version 0).\n`headers` field is dropped for kafka prior to version `0.11` (produce API version 0-2, magic version 0-1).\n\n### Synchronized Produce API\n\n```erlang\nbrod:produce_sync(_Client    = brod_client_1,\n                  _Topic     = \u003c\u003c\"brod-test-topic-1\"\u003e\u003e,\n                  _Partition = 0,\n                  _Key       = \u003c\u003c\"some-key\"\u003e\u003e,\n                  _Value     = \u003c\u003c\"some-value\"\u003e\u003e).\n```\n\nOr block calling process until Kafka confirmed the message:\n\n```erlang\n{ok, CallRef} =\n  brod:produce(_Client    = brod_client_1,\n               _Topic     = \u003c\u003c\"brod-test-topic-1\"\u003e\u003e,\n               _Partition = 0,\n               _Key       = \u003c\u003c\"some-key\"\u003e\u003e,\n               _Value     = \u003c\u003c\"some-value\"\u003e\u003e),\nbrod:sync_produce_request(CallRef).\n```\n\n### Produce One Message and Receive Its Offset in Kafka\n\n```erlang\nClient = brod_client_1,\nTopic  = \u003c\u003c\"brod-test-topic-1\"\u003e\u003e,\n{ok, Offset} = brod:produce_sync_offset(Client, Topic, 0, \u003c\u003c\u003e\u003e, \u003c\u003c\"value\"\u003e\u003e).\n```\n\n### Produce with Random Partitioner\n\n```erlang\nClient = brod_client_1,\nTopic  = \u003c\u003c\"brod-test-topic-1\"\u003e\u003e,\nok = brod:produce_sync(Client, Topic, random, Key, Value).\n```\n\n### Produce a Batch\n\n```erlang\nbrod:produce(_Client    = brod_client_1,\n             _Topic     = \u003c\u003c\"brod-test-topic-1\"\u003e\u003e,\n             _Partition = MyPartitionerFun,\n             _Key       = KeyUsedForPartitioning,\n             _Value     = [ #{key =\u003e \"k1\", value =\u003e \"v1\", headers =\u003e [{\"foo\", \"bar\"}]}\n                          , #{key =\u003e \"k2\", value =\u003e \"v2\"}\n                          ]).\n```\n\n### Handle Acks from Kafka as Messages\n\nFor async produce APIs `brod:produce/3` and `brod:produce/5`,\nthe caller should expect a message of below pattern for each produce call.\n\n```erlang\n#brod_produce_reply{ call_ref = CallRef %% returned from brod:produce\n                   , result   = brod_produce_req_acked\n                   }\n```\n\nAdd `-include_lib(\"brod/include/brod.hrl\").` to use the record.\n\nIn case the `brod:produce` caller is a process like `gen_server` which\nreceives ALL messages, the callers should keep the call references in its\nlooping state and match the replies against them when received.\nOtherwise `brod:sync_produce_request/1` can be used to block-wait for acks.\n\nNOTE: If `required_acks` is set to `none` in producer config,\nkafka will NOT ack the requests, and the reply message is sent back\nto caller immediately after the message has been sent to the socket process.\n\nNOTE: The replies are only strictly ordered per-partition.\ni.e. if the caller is producing to two or more partitions,\nit may receive replies ordered differently than in which order\n`brod:produce` API was called.\n\n### Handle Acks from Kafka in Callback Function\n\nAsync APIs `brod:produce_cb/4` and `brod:produce_cb/6` allow callers to\nprovided a callback function to handle acknowledgements from kafka.\nIn this case, the caller may want to monitor the producer process because\nthen they know that the callbacks will not be evaluated if the producer is 'DOWN',\nand there is perhaps a need for retry.\n\n## Consumers\n\nKafka consumers work in poll mode. In brod, `brod_consumer` is the poller,\nwhich is constantly asking for more data from the kafka node which is a leader\nfor the given partition.\n\nBy subscribing to `brod_consumer` a process should receive the polled message\nsets (not individual messages) into its mailbox.\n\nIn brod, we have so far implemented two different subscribers\n(`brod_topic_subscriber` and `brod_group_subscriber`),\nhopefully covered most of the common use cases.\n\nFor maximum flexibility, applications may implement their own\nper-partition subscriber.\n\nBelow diagrams illustrate 3 examples of how subscriber processes may work\nwith `brod_consumer`.\n\n### Partition subscriber\n\n![partition subscriber architecture](https://cloud.githubusercontent.com/assets/164324/19621677/5e469350-9897-11e6-8c8e-8a6a4f723f73.jpg)\n\nThis gives the best flexibility as the per-partition subscribers work\ndirectly with per-partition pollers (`brod_consumer`s).\n\nThe messages are delivered to subscribers in message sets (batches),\nnot individual messages, (however the subscribers are allowed to\nack individual offsets).\n\nExample:\n```erlang\nok = brod:start_client([{\"localhost\", 9092}], my_client). % one client per application is enough\nok = brod:start_consumer(my_client, \u003c\u003c\"my_topic\"\u003e\u003e, []).\n\n% Now in a separate process for each partition of my_topic call:\n{ok, ConsumerPid} = brod:subscribe(my_client, self(), \u003c\u003c\"my_topic\"\u003e\u003e, Partition, []).\n% The process should now receive messages sets as regular messages\n```\n\n### Topic subscriber (`brod_topic_subscriber`)\n\n![topic subscribe flow](https://cloud.githubusercontent.com/assets/164324/19621951/41e1d75e-989e-11e6-9bc2-49fe814d3020.jpg)\n\nA topic subscriber provides the easiest way to receive and process messages from\nALL partitions of a given topic. See\n[brod_demo_cg_collector](https://github.com/kafka4beam/brod/blob/master/test/brod_demo_cg_collector.erl) and\n[brod_demo_topic_subscriber](https://github.com/kafka4beam/brod/blob/master/test/brod_demo_topic_subscriber.erl) for example.\n\nUsers may choose to implement the `brod_topic_subscriber` behaviour callbacks\nin a module, or simply provide an anonymous callback function to have the\nindividual messages processed.\n\n### Group subscriber (`brod_group_subscriber`)\n\n![group subscriber flow](https://cloud.githubusercontent.com/assets/164324/19621956/59d76a9a-989e-11e6-9633-a0bc677e06f3.jpg)\n\nSimilar to topic subscriber, the `brod_group_subscriber` behaviour callbacks are\nto be implemented to process individual messages. See\n[brod_demo_group_subscriber_koc](https://github.com/kafka4beam/brod/blob/master/test/brod_demo_group_subscriber_koc.erl) and\n[brod_demo_group_subscriber_loc](https://github.com/kafka4beam/brod/blob/master/test/brod_demo_group_subscriber_loc.erl) for\nexample.\n\nA group subscriber is started by giving a set of topics, some\n(maybe none, or maybe all) of the partitions in the topic set will be\nassigned to it, then the subscriber should subscribe to ALL the assigned\npartitions.\n\nUsers may also choose to implement the `brod_group_member` behaviour (callbacks\nfor `brod_group_coordinator`) for a different group subscriber (e.g. spawn\none subscriber per partition), see [brucke](https://github.com/klarna/brucke)\nfor example.\n\n#### Example of group consumer which commits offsets to Kafka\n\n```erlang\n-module(my_subscriber).\n-include_lib(\"brod/include/brod.hrl\"). %% needed for the #kafka_message record definition\n\n-export([start/1]).\n-export([init/2, handle_message/4]). %% callback api\n\n%% brod_group_subscriber behaviour callback\ninit(_GroupId, _Arg) -\u003e {ok, []}.\n\n%% brod_group_subscriber behaviour callback\nhandle_message(_Topic, Partition, Message, State) -\u003e\n  #kafka_message{ offset = Offset\n                , key   = Key\n                , value = Value\n                } = Message,\n  error_logger:info_msg(\"~p ~p: offset:~w key:~s value:~s\\n\",\n                        [self(), Partition, Offset, Key, Value]),\n  {ok, ack, State}.\n\n%% @doc The brod client identified ClientId should have been started\n%% either by configured in sys.config and started as a part of brod application\n%% or started by brod:start_client/3\n%% @end\n-spec start(brod:client_id()) -\u003e {ok, pid()}.\nstart(ClientId) -\u003e\n  Topic  = \u003c\u003c\"brod-test-topic-1\"\u003e\u003e,\n  %% commit offsets to kafka every 5 seconds\n  GroupConfig = [{offset_commit_policy, commit_to_kafka_v2},\n                 {offset_commit_interval_seconds, 5}\n                ],\n  GroupId = \u003c\u003c\"my-unique-group-id-shared-by-all-members\"\u003e\u003e,\n  ConsumerConfig = [{begin_offset, earliest}],\n  brod:start_link_group_subscriber(ClientId, GroupId, [Topic],\n                                   GroupConfig, ConsumerConfig,\n                                   _CallbackModule  = ?MODULE,\n                                   _CallbackInitArg = []).\n```\n\n## Authentication support\n\nbrod supports SASL `PLAIN`, `SCRAM-SHA-256` and `SCRAM-SHA-512` authentication mechanisms out of the box.\nTo use it, add `{sasl, {Mechanism, Username, Password}}` or `{sasl, {Mechanism, File}}` to client config.\nWhere `Mechanism` is `plain | scram_sha_256 | scram_sha_512`, and `File` is the path to a text file\nwhich contains two lines, first line for username and second line for password\n\nAlso, brod has authentication plugins support with `{sasl, {callback, Module, Opts}}` in client config.\nAuthentication callback module should implement `kpro_auth_backend` behaviour.\nAuth function spec:\n\n```erlang\nauth(Host :: string(), Sock :: gen_tcp:socket() | ssl:sslsocket(),\n     Mod :: gen_tcp | ssl, ClientId :: binary(),\n     Timeout :: pos_integer(), SaslOpts :: term()) -\u003e\n        ok | {error, Reason :: term()}\n```\n\nIf authentication is successful - callback function should return an atom `ok`, otherwise - error tuple with reason description.\nFor example, you can use [`brod_gssapi` plugin](https://github.com/kafka4beam/brod_gssapi) for SASL GSSAPI authentication.\nTo use it - add it as dependency to your top level project that uses brod.\nThen add `{sasl, {callback, brod_gssapi, {gssapi, Keytab, Principal}}}` to client config.\nKeytab should be the keytab file path, and Principal should be a byte-list or binary string.\n\nSee also: \u003chttps://github.com/klarna/brod/wiki/SASL-gssapi-(kerberos)-authentication\u003e\n\n### Additional Auth plugins\n\n- [brod_oauth](https://github.com/HCA-Healthcare/brod_oauth)  - OAuth Bearer support\n\n## Other API to play with/inspect kafka\n\nThese functions open a connection to kafka cluster, send a request,\nawait response and then close the connection.\n\n```erlang\nHosts = [{\"localhost\", 9092}].\nTopic = \u003c\u003c\"topic\"\u003e\u003e.\nPartition = 0.\nTimeout = 1000.\nTopicConfigs = [\n  #{\n    configs =\u003e [ #{name  =\u003e \u003c\u003c\"cleanup.policy\"\u003e\u003e, value =\u003e \"compact\"}],\n    num_partitions =\u003e 1,\n    assignments =\u003e [],\n    replication_factor =\u003e 1,\n    name =\u003e Topic\n  }\n].\nbrod:get_metadata(Hosts).\nbrod:create_topics(Hosts, TopicConfigs, #{timeout =\u003e Timeout}).\nbrod:get_metadata(Hosts, [Topic]).\nbrod:resolve_offset(Hosts, Topic, Partition).\nbrod:delete_topics(Hosts, [Topic], Timeout).\n```\n\nCaution the above delete_topics can fail if you do not have `delete.topic.enable` set to true in your kafka config\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkafka4beam%2Fbrod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkafka4beam%2Fbrod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkafka4beam%2Fbrod/lists"}