Git Product home page Git Product logo

kp's Introduction

kp

Library for handing Kafka messages with retries

How it works

Each KP instance create a kafka sarama client which will listen to 2 topics: main topic and retry topic. The Retry topic will be prepended with the consumer group name such that each instance could have its own retry and dead letter topics. This will enable a case such that you have two services that listen to the same topic but one service might fail the topic, with this it would only retry on that service and not the other one.

Code Example: (see examples)

func main() {
	cfg, err := config.LoadConfig()
	if err != nil {
		panic(err)
	}
	retryCount := 10
	consumerGroup := "simple-service" // usually the name of your service
	backoffDuration := time.Second * 1 // set to 0 for no backoff

	processor := kp.NewKafkaProcessor("main-topic", "retry-main-topic", "dead-main-topic", retryCount, consumerGroup, kp.KafkaConfig{KafkaBootstrapServers: strings.Split(cfg.KafkaConfig.KafkaBootstrapServers, ",")}, backoffDuration)
	// retry topic becomes "simple-service-retry-main-topic"
	// dead letter topic becomes "simple-service-dead-main-topic"
	processor.Process(func(key string, message string, retries int, rawMessage *sarama.ConsumerMessage) error {
		err := processMessage(message)
		if err != nil {
			log.Printf("Error processing message: %s", err)
			return err
		}
		log.Println("successfully processed message")
		return nil
	})

	processor.Start()

}

To disable retries, just set retries to 0

Exponential backoff

This library supports exponential backoff. To use a backoff policy, set the backoffDuration to anything above 1. To disable the backoff policy, set the backoffDuration to 0. Backoff happens on the whole client which will slow down all mesaages. When a message is successful, the backoffDuration is reduced.

Topics

KP Uses 3 topics: main topic, retry topic and dead letter topic. You are able to modify the retry and dead letter topics like so:

processor := kp.NewKafkaProcessor(
	cfg.Kafka.CardReplacementTopic,
	"retry-"+cfg.Kafka.CardReplacementTopic,
	"deadletter-"+cfg.Kafka.CardReplacementTopic,
	10,
	"card-delivery-service",
	kp.KafkaConfig{KafkaBootstrapServers: strings.Split(cfg.Kafka.KafkaBootstrap, ",")},
	time.Second*5,
	)

This is useful when you have a worker that listens to multiple topics and each topic needs to have its own retry and dead letter topic.

For retry and deadletter topics they are generated with the consumer group. ex:

  topic: test
  retrytopic: retry
  deadlettertopic: deadletter
  consumergroup: group

resulting topics:
    retrytopic: group-retry
    deadlettertopic: group-deadletter


resulting topic format: <consumer group>-<retry|deadletter topic>

kp's People

Contributors

bludot avatar cyberhck avatar honestbank-bot avatar josefmp avatar kelu-diao avatar maetolay avatar poom avatar visaruttt avatar yoshinaz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kp's Issues

finalize docs for v2

  • readme
  • docs proofread
  • docs team proofread
  • docs proofread final
  • write docs for the 2 producers (after the #81 )

can we write consumer as a middleware?

if there's a middleware that takes the consumer as input, and then for every message with nil value, takes a peek at the message and continues the flow with the message from the source, then the consumer can also become just another middleware.

This will enable KP to work with other message buses or even message queues.
For example: SNS would have a SNSConsumer middleware (here, we wouldn't need a retry / deadletters because SNS supports this out of the box)

and RabbitMQ Consumer. would have it's own RabbitMQConsumer middleware. (Here, we'd have a retry middleware that updates the message header)

allow untyped producer to produce to any topic.

Is your feature request related to a problem? Please describe.
I'm always frustrated when I need to produce to 2 topics from my business logic and end up needing 2 different producer essentially forcing 2 connection.

Describe the solution you'd like
Change the constructor such that it no longer asks for the topic, and doesn't overwrite the topic in ProduceRaw method. Since kafka.Message already has topic in it, we'll be able to send the message to any topic we want.

Forcing the topic in place can be done in typed producer.

Describe alternatives you've considered
I've considered wrapping, but ends up needing multiple producer under the hood.

create a untyped producer

Is your feature request related to a problem? Please describe.
I'm always frustrated when I have to use KP without a schema registry but it requires us to use schema registry.

Describe the solution you'd like
Allow a producer to be used without a schema registry for retry and deadletter middleware as well as produce messages without a dependency on schema registry.

Describe alternatives you've considered
We've considered writing our own producer but that's duplicated multiple places.

Additional context
Because of above, duplicated producer, it makes sense for kp to expose a producer without dependencies on schema registry.

individual middlewares in their own package

currently middlewares package exports all middleware and sometimes it's exposing too much information.

Maybe the middleware package should have subpackage, so individual middlewares get their own individual package (that way they can add more files as well)

support producer middlewares

Is your feature request related to a problem? Please describe.
Every once in a while users of KP come up with something that KP can't do or won't do easily. In this case, we want to use Avro serialization and whatnot, but we want to be able to also set the Kafka key.

If we added a parameter for every request, the signature will eventually pollute and we'll have to end up writing a v3 which I really would like to avoid.

Describe the solution you'd like
If producers accepted middleware then that middleware would be able to do anything they want. Extra metadata could be passed through context. This also means all Produce fields will now accept context.

While this does mean a breaking change, it will avoid any potential change in the future.

The question here is though: should we add middleware on UntypedProducer or a typed producer? Whatever we chose, we can then create a separate tracing middleware so that default producers are free of any tracing logic as well.

Describe alternatives you've considered
An alternative conversation went along forking the repo temporarily (because the need was temporary), it also went in adding an extra field in the Produce method. Using the untyped producer directly and exposing internal things like schema registry etc. None of them are as flexible/good as just supporting middleware while producers.

Additional context
I'm inclined towards untyped producers having middleware support, but Typed producers also expose the same method which internally calls the untyped producer as well. This way both producers can happily use middlewares.

should producer really inject trace headers?

If so, then what kind of trace is it supporting? KP's API has an option to not use this middleware but rather come up with our own. But the producer doesn't support middleware so is it really correct to inject headers as we see fit?

I'm inclined towards a no.

Maybe producer also should support a bit of middleware, that way people can add tracing only if they wanted to.

retries and deadletter should become a middleware

with #39 we'll have a way for middleware to add topics it wants to listen to, so it'll be possible for retries and deadletters to be yet another middleware.

While doing this, we'll also remove the .WithRetries like API.

document why keys aren't settable in typed producer

while #82 will allow us to set keys to a message through middleware, we don't allow this by design in typed producer.

in 99% of the cases, we're not supposed to use keys, it's supposed to be managed by kafka.
in the odd times when we do need that functionality we should either use a middleware or raw producer.

The initial KP release was such brutal that it was not possible to set key at all, but we needed the functionality to have keys and realized we can't avoid 100% of the time. I'll write this in docs later.

kp should change the generics usage from core API

this way, kp consumer can in theory be used without a schema registry or strongly typed definitions.

But we'll add another middleware that takes generics and accepts multiple handler patterns so that we can attach multiple "handlers" depending on what type of message we're getting. This way we keep strongly typed option available.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.