-
Notifications
You must be signed in to change notification settings - Fork 592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Heartbeat provisioner #513
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: n3wscott If they are not already assigned, you can assign the PR to them by writing The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
target: | ||
kind: Service | ||
apiVersion: serving.knative.dev/v1alpha1 | ||
name: message-dumper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it possible to also use an image
here ?
I see you building your message-dumper
Golang-container using ko
, but was wondering if ko
is required for building "sources" ? (and other artifacts in the new spec) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ko is just a nice way to push containers to a registry if you are using go.
name: heartbeats | ||
arguments: | ||
label: "<3" | ||
period: 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could the kind: Source
also reference to an image
, backing the code (if not using ko
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, the specific images to use should be an implementation detail of the Provisioner. If the provisioner chooses to expose an image, then it could be defined in the Source arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this. I intended to learn something with the heartbeat source and I have... :D
Isn't that alot of code for an event-source and the provisioner ? 🤔 |
|
||
func send() { | ||
hb.Sequence++ | ||
resp, err := http.Post(remote, "application/json", body()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here, the source invokes the target (aka ksvc
), why would it directly invoke HTTP?
I would think think it uses a channel
, that might have an http implementation (or something else)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matzew There's no indication here whether remote
is a dns name for a Channel, KService or anything else. Which is good for this level. How the value for remote
is set is a higher level concern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the remote
is somehow injected - fine.
I was more asking. Do we need (perhaps in the future) some higher level API ? that this would use a channel
instead of an http client (e.g. when the spec supports other protocols as well). Perhaps out of scope for now...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is assuming that the channel speaks http. So the source makes a channel, waits for it to resolve, and then gives the pod the resolved channel host as remote
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is using a channel. The heartbeat code just does not know it. :D
Looking in the code/example, I see a subscription for a Channel(well Source atm) targeting a function. OK. However, I wonder how this would look like, if the subscription would not include a Also, I see the source, in the example is doing direct HTTP invocation. Isn't there some "channel" class/object missing, that the source would use instead ? I'd think this is needed for better abstraction Here is an example for a channel to channel routing, and than eventually that second channel has a subscription, which will trigger the HTTP Channel to ChannelapiVersion: eventing.knative.dev/v1alpha1
kind: Subscription
metadata:
name: love-dumper1
namespace: default
spec:
from:
kind: Channel
apiVersion: eventing.knative.dev/v1alpha1
name: love
result:
target:
kind: Channel
apiVersion: eventing.knative.dev/v1alpha1
name: love-dumper-output
Receive from second ChannelapiVersion: eventing.knative.dev/v1alpha1
kind: Subscription
metadata:
name: love-dumper2
namespace: default
spec:
from:
kind: Channel
apiVersion: eventing.knative.dev/v1alpha1
name: love-dumper-output
call:
target:
kind: Service
apiVersion: serving.knative.dev/v1alpha1
name: message-dumper
Is this a valid example? would it work with the proposed spec? Why does the example do direct HTTP invocations? This assumes changes from @scothis in n3wscott#4 are accepted (e.g. only Channel is subscribable) |
@@ -49,6 +50,7 @@ type ProvideFunc func(manager.Manager) (controller.Controller, error) | |||
// be added to the default providers list. | |||
var ExperimentalControllers = map[string]ProvideFunc{ | |||
"subscription.eventing.knative.dev": subscription.ProvideController, | |||
"heartbeats-provisioner": heartbeatcontroller.ProvideController, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Source should be deployed independently. Otherwise, this encourages all other Source implementations to want to be included in this repo and compiled into the controller binary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just for experimenting with the model. Decouple the how deployment works with what the reconciling is like.
// +optional | ||
// +patchMergeKey=name | ||
// +patchStrategy=merge | ||
Provisioned []ProvisionedObjectStatus `json:"provisioned,omitempty" patchStrategy:"merge" patchMergeKey:"name"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name
does not uniquely identify a resource since two resource can have the same name, but different types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. I moved this code to #517
Will fix there.
|
||
func send() { | ||
hb.Sequence++ | ||
resp, err := http.Post(remote, "application/json", body()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matzew There's no indication here whether remote
is a dns name for a Channel, KService or anything else. Which is good for this level. How the value for remote
is set is a higher level concern.
defer resp.Body.Close() | ||
} | ||
|
||
func body() io.Reader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a CloudEvent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not need to be a CloudEvent. It can be though.
name: heartbeats | ||
arguments: | ||
label: "<3" | ||
period: 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, the specific images to use should be an implementation detail of the Provisioner. If the provisioner chooses to expose an image, then it could be defined in the Source arguments.
return reconcile.Result{}, nil | ||
} | ||
|
||
original := source.DeepCopy() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line will cause issue if there is any kind of cache within r.client
since the "original" is the copy and the true original is being mutated.
Spec: v1alpha1.ChannelSpec{ | ||
Provisioner: &v1alpha1.ProvisionerReference{ | ||
Ref: &corev1.ObjectReference{ | ||
Name: "in-memory-channel", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the heartbeat Source require the in-memory-channel Provisioner? It minimally needs to be documented as such.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is demo code... :D
|
||
} | ||
|
||
pod, err := r.getPod(ctx, source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Deployment would offer better semantics around updates, which are not handled today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to a deployment.
Look now, the source is 72 lines And we don't intend average people to implement Provisioners. The hope is there will be an ecosystem of Provisioners where you can select the one that will do the job you need to do. |
@n3wscott Thanks for the reply. First of all, great: the source now is really simple. cool. I was also hoping for a rich eco-system of Source/Channel provisioners. i like the changed version of this better than before your changes |
@n3wscott question: the Source, instead of doing hard coded http. Could it write to some more abstract |
@matzew My understanding is that so far between Source and Channel there is only http possible. If other protocols were supported, the (Source?) Provisioner would need to check, if the according Source and Channel are able to communicate. In #508 I was thinking of a Source that uses AMQP to deliver data to a Channel. |
@deissnerk I think the source, now just uses direct HTTP. using the "remote" ass its URL I think that a channel could be (in the future?) passed in too cc @n3wscott |
@matzew But
|
remote is misnamed, it should be called |
I used remote because the sample was taken from another demo app that was used that knows nothing about eventing... |
The following is the coverage report on pkg/.
|
@n3wscott do we still want this in the repo or can it be moved to eventing-sources? |
Closed in favor of https://github.com/knative/eventing-sources |
Updating patches to latest
* Add TLS updates to main Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com> * Add TLS issuers Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com> --------- Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
This is a demo of a simple heartbeat container.
Steps to run:
ko publish github.com/knative/eventing/pkg/provisioners/heartbeats/cmd/
ko apply -f https://raw.githubusercontent.com/n3wscott/knative-playground/master/cmd/dumper/dumper.yaml
ko apply -f config/500-controller.yaml
kubectl apply -f pkg/provisioners/heartbeats/config/examples/
This will heartbeat into a generated channel, and then a subscription tie the channel to the message dumper.
TODO: there are changes I had to make to the eventing api, I will move those changes to another PR asap.