components-contrib icon indicating copy to clipboard operation
components-contrib copied to clipboard

[Proposal] Create an adapter to use PubSub components as Bindings

Open pkedy opened this issue 4 years ago • 15 comments
trafficstars

Currently, there are several bindings that have a pubsub counterpart (E.g. Kafka, Rabbit, Pulsar, NATS, Redis). In many cases the code in the PubSub component is far more robust. Given the similarity between bindings (Data + Metadata) and pubsub (Topic + Data + Metadata), an adapter could be used that specifies the read/invoke topics to subscribe and publish to. The primary motivation is that adapter reuses code and users can expect the same behavior between the binding and pubsub.

Here are some issues that would possibly be resolved for Kafka:

#1277 #1084 #955 #1006 #168

The downside is that if there are current inconsistencies in the component settings, then migrating to this approach would break existing versions. Since none of these components are marked as stable (yet), now is the time to do this if at all.

pkedy avatar Nov 15 '21 21:11 pkedy

It is a design issue as bindings are more abstract than pubsub, we should better guide users to choose the most suitable one instead of making the two more obscure.

/cc @artursouza @yaron2

daixiang0 avatar Nov 16 '21 01:11 daixiang0

It is a design issue as bindings are more abstract than pubsub, we should better guide users to choose the most suitable one instead of making the two more obscure.

Hi, @daixiang0! I don't disagree with this statement. I have opinions about this duality as well; however, users are already using the binding versions of pubsub components and experiencing issues that are not present in the pubsub component. This proposal isn't intended to debate the merit of bindings for message brokers. Instead, this proposal aims to remove redundant or inferior code in favor of reusing the more robust pubsub code. If anything it provides a simpler, more maintainable option for developers to subscribe/publish to topics without having to configure or have knowledge of pubsub/topics inside their applications.

pkedy avatar Nov 16 '21 17:11 pkedy

Might this also be improved by simply refactoring pubsub and binding components to use shared code like the Redis components? That would allow some foundational aspects like service connectivity, authentication, etc... to be used in both even if the functionality diverges.

sthussey avatar Dec 05 '21 16:12 sthussey

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue, help wanted or triaged/resolved) or other activity occurs. Thank you for your contributions.

dapr-bot avatar Jan 04 '22 16:01 dapr-bot

This issue has been automatically closed because it has not had activity in the last 37 days. If this issue is still valid, please ping a maintainer and ask them to label it as pinned, good first issue, help wanted or triaged/resolved. Thank you for your contributions.

dapr-bot avatar Jan 11 '22 16:01 dapr-bot

I have a question about the design principle of pubsub and binding:

Since we have pubsub components for these message broker, why we still provide binding components for them?

Do we provide more capabilities than pubsub in binding for these message broker? For this question I checked kafka binding and kafka pubsub, the answer is NO.

And I checked carefully for the code of kafka binding and kafka pubsub.

output binding

In kafka output binding, only "create" operation is supported, and the functionality is totally the same as publish() in kafka pubsub, while the implementation code of publish() in kafka pubsub is better, or more careful to handle details: 1. check if component is closed. 2. support more metadata, not only "partitionKey".

input binding

The implementation code in input binding Read() method is very similar to the Subscribe() method of pubsub. The biggest difference is that there is a retry logic in pubsub. This retry logic is also in the ConsumeClaim() of ConsumerGroupHandler.

So the question is that why we need retry in kafka subscribe but not need in kafka input binding? It seems the reason is due to the code implementation of kafka binding.

My conclusion about kafka binding is that it can be replaced with kafka pubsub from the point of view of functionality.

Discuss

I list some possible solution to discuss:

  • Proposal 1 : Remove binding components for message brokers, since their pubsub components are enough.
  • Proposal 2 : Keep binding components for message brokers, add adapters to the pubsub components and reuse the code in component level. As @pkedy suggested in this issue.
  • Proposal 3 : Keep binding components for message brokers, extract the common code of kafka and reuse them in both kafka binding and kafka pubsub. In fact, for redis, we have already do this code reuse. Please have a look at internal/component/redis
  • Proposal 4 : this is mixed proposal —— take proposal 2 first, and mark the kafka binding components as "deprecated", later take proposal 1 to delete kafak binding.

Some background: I'm taking the task to add certification test for kafka binding, yet I found that to do this I have to repeat all the work of certification test for kafka pubsub. I don't want to simply control + c && control + v. This is not a good choice. I would like to do this certification after we discussed and made decision.

@pkedy: thank for your good suggestion about this issue.

skyao avatar Apr 26 '22 10:04 skyao

@skyao I agree. I think we should remove/deprecate Kafka input binding.

artursouza avatar Apr 26 '22 18:04 artursouza

We should not remove the bindings that have pub/sub equivalents, specifically Kafka, because they allow users to contribute and use more specialized features from the underlying system. For example, a Kafka binding can expose an API that returns the number of messages in a topic.

The fact it's not there today does not mean we should block this functionality from being added at any point in the future by removing the component.

yaron2 avatar Apr 26 '22 18:04 yaron2

That is a great point, @yaron2. Does it mean we should not simply make the Kafka binding a wrap of the pubsub component and keep those as completely separate implementations?

artursouza avatar Apr 26 '22 19:04 artursouza

We can use the suggested adopter pattern to reuse what code we can (if at all, but I believe most code can be reused).

As long as we allow bindings to add operations (which is their goal for flexibility) and their own unique metadata, we can refactor the code however we see fit.

yaron2 avatar Apr 26 '22 19:04 yaron2

We can use the suggested adopter pattern to reuse what code we can (if at all, but I believe most code can be reused).

As long as we allow bindings to add operations (which is their goal for flexibility) and their own unique metadata, we can refactor the code however we see fit.

Hi, yaron, let me try to do a code refactory for kafka pubsub and binding, I will extract some common code to reuse, and use adapter for publish (outpub binding create operation) & subscribe (input binding read method).

skyao avatar Apr 27 '22 01:04 skyao

@artursouza @yaron2 @pkedy I have submitted the first version of the code refactory for kafka pubsub component and kafka binding component accrording to above discussion.

I split this code refactory into two parts:

  1. refactory kafka pubsub compoent to extract the common kafka code

    These common kafka code is moved to internal/kafka .

    Kafka pubsub compoent now is based on this common code and it adapters its pubsub api method to the common code like init() / publish() / subscribe() / close().

    This refactory should be safe since it only split and move the code, no functionality change.

  2. refactory kafka binding component to reuse the common kafka code

    This is a BIG change to kafka binding component since now it's code base is moved to the common kafka code extracting from kafka pubsub component.

    The benefit is that now kafka component is have the same features and implementations as kafka pubsub component.

    The challenge is that we need to careful handle the difference.

The second PR should be reviewed very carefully.

skyao avatar Apr 29 '22 02:04 skyao

I suggest we keep the adapted version as kafka binding v2 and keep the old version as-is in v1. This way, we don't break existing apps. Even as alpha component, kafka is a popular broker.

artursouza avatar May 04 '22 03:05 artursouza

Do we know of breaking changes here?

yaron2 avatar May 04 '22 03:05 yaron2

Do we know of breaking changes here?

Yes. The E2E tests are failing already because of that in the PR https://github.com/dapr/dapr/actions/runs/2243065335

artursouza avatar May 04 '22 03:05 artursouza