Refine bus monitor#88
Conversation
| } | ||
|
|
||
| func (m *Monitor) removeBus(namespace string, name string) error { | ||
| // nothing to do |
There was a problem hiding this comment.
Should this mark this monitor helper as "unusable"?
| func (m *Monitor) isChannelKnown(subscription channelsv1alpha1.Subscription) bool { | ||
| channelKey := makeChannelKeyFromSubscription(subscription) | ||
| summary := m.getChannelSummary(channelKey) | ||
| return summary != nil && summary.Channel != nil |
There was a problem hiding this comment.
Why the need for summary.Channel != nil (similar checks appear at other places). Seems like this should already be satisfied by the map lookup
There was a problem hiding this comment.
In the case where a subscription resource is loaded before the channel resource, there won't be a channel in the map yet.
There was a problem hiding this comment.
Isn't that the summary != nil part? My point is: can summary be non nil but with its Channel member nil? I would expect not
|
No description provided. |
|
@vaikas-google We think this is about ready to go. Can you take a look? |
Interesting -- I'd have thought that provisioning a bus would fall squarely on the operator. Would you expect the developer or the operator to provision the kafka cluster in the case of the kafka bus? |
That's a fair point. I'd expect the operator to be actively involved with deploying Kafka since that's certainly not set-and-forget. |
|
@vaikas-google @evankanderson what are the next steps here? |
|
I think in the name of continuing with the prototyping work and figuring out the rough shape of the APIs involved and getting the data plane wired in to bindings I'd be fine to get this merged in. However, in parallel we should probably put together some time and thinking of what the control plane API looks like and what belongs there and what doesn't. I could certainly see separate steps:
Seems like there's some concerns with the current definitions so we should have some design discussions about the direction we all feel comfortable there, but I also am sensitive to making some progress with the understanding that these things might have to change. @evankanderson thoughts? |
|
@grantr pointed me to https://kubernetes.io/docs/concepts/storage/storage-classes/, which seems to be addressing a similar problem around many possible implementations of storage for persistent volumes in kubernetes. Since my concern is actually about #66, rather than this PR, I don't necessarily want to block getting this in. But I'd like to open a discussion about how to refactor the existing bus definitions towards a CRD which might look more like the StorageClass style, e.g. apiVersion: eventing.knative.dev/v1alpha1
kind: Bus
metadata:
name: prod-kafka
provisioner: kafka
parameters: # A map[string]string
connectString: "mykafka..."
reclaimAfter: "20d"
... |
|
@mattmoor also had some good observations this morning that a Bus feels like it is more likely to be a cluster-wide resource (thinking about Kafka or the equivalent), rather than a per-namespace resource. If a Bus is cluster-wide, that also suggests provisioning by an operator. It seems like Channels should probably be per-namespace, which means that the Channel reference to the bus should include both a namespace and a name, unless the names are explicitly cluster-wide (i.e. |
|
Thanks for the explanation of the monitor -- it wasn't clear that it was actually a controller framework. I think my main question/point was that it should be possible to have multiple controllers managing resources of the same type, as long as ownership is clearly defined between controllers. (I.e. you could have a Kafka controller and a PubSub controller both watching Channels or Buses, as long as it's clear from the resource definitions which one should act on that particular resource.) We'd probably also want a webhook to keep resources from changing from one controller regime to another without a delete. |
| subscriptionsSynced cache.InformerSynced | ||
| cache map[channelKey]*channelSummary | ||
| provisionedChannels map[channelKey]*channelsv1alpha1.Channel | ||
| provisionedSubscriptions map[subscriptionKey]*channelsv1alpha1.Subscription |
There was a problem hiding this comment.
What are the cache, provisionedChannels, and provisionedSubscriptions maps used for? Is the information in them recoverable if the monitor pod is restarted?
There was a problem hiding this comment.
Yes, these caches are idempotent and will repopulate from the informer when the pod restarts.
Is this cache different from an informer? Informers are already caches that automatically stay current with Kubernetes state and can be queried by name and selector (see the generated Listers). |
|
I'm in full agreement that the model proposed here needs further iteration. #66 was a green field spike, this PR uses the learnings from implementing PubSub (#98) and Kafka (#99) buses. With these PRs I feel much more comfortable that we can iterate on the model quicker while testing our assumptions with running code. The notion of StorageClasses as a model for a bus is something that we had talked about in the context of riff, it's interesting to see the same idea arise organically. One possible downside of following that model is that storage is often a tradeoff between speed and cost. Many of the classes are named The more I think about it, the more I agree that a Bus is primarily an operator construct. Their is a direct analogy between a message broker and a database. In the service broker world, the operator decides which services and configurations are available, while the developer consumes those services.
I completely agree. The monitor is configured for a single bus, bus receives all channels and subscriptions via the informers. The first thing the bus does is filter out channels that are for other buses and subscriptions that are for other channels. The handler funcs on the monitor are only fired for types that the bus needs to handle. There's a bit of extra complexity in this implementation to handle the case of a channel switching buses, or a subscription switching channels. I agree that's a case we should disallow and simplify the monitor accordingly. |
There are two key purposes behind these caches:
|
| // apply arguments | ||
| if arguments != nil { | ||
| for _, arg := range *arguments { | ||
| if _, ok := known[arg.Name]; ok { |
There was a problem hiding this comment.
The condition is inverted. Should read if !ok
| m.bus = bus | ||
|
|
||
| glog.Info("Starting workers") | ||
| // Launch two workers to process Bus resources |
There was a problem hiding this comment.
comment shouldn't say "two", depends on the value of threadiness
There was a problem hiding this comment.
good artists copy, great artists steal.
|
/lgtm |
Not sure this is exactly what you're referring to, but indeed in the Kafka Bus implementation for example, I craft the kafka topic name (which can be seen as an implementation detail from the channel user perspective) as being a combination of the channel name + namespace. This way, assuming there is on Bus Custom Resource instance for one Kafka broker instance (certainly both the responsibility of an operator) then channels from any namespace can use it without clash. If however, we envision that many Bus Custom Resource instances can share the same backing broker, then we'll want to factor in the name (and possibly namespace if we keep it namespaced) of the Bus itself. IMO the "compromise" that makes the most sense is
This is certainly something we had to consider working with riff, and there is a whole range of scenarios to cover |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: scothis, vaikas-google The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Proposed Changes