openwhisk-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michele Sciabarra <mich...@sciabarra.com>
Subject Re: [Long] I implemented websocket support for the Golang and related runtimes:
Date Tue, 22 Jan 2019 14:51:07 GMT
Thanks Markus. At this stage I am writing an example that uses OpenWhisk actions alone. 

Trying to understand if it is appropriate or not to have this websocket feature allowing to
deploy action runtimes "alone" in kubernets as websocket servers...If there is not consensus
I my drop my proposal altogheter.

-- 
  Michele Sciabarra
  michele@sciabarra.com

----- Original message -----
From: Markus Thömmes <markusthoemmes@apache.org>
To: dev@openwhisk.apache.org
Subject: Re: [Long] I implemented websocket support for the Golang and related runtimes:
Date: Tue, 22 Jan 2019 14:29:50 +0100

Hi,

leaving a few remarks. Thanks as always for your hard work Michele, you're
cranking out a lot of stuff! Great job!

1. On the initial problem statement (and for your book): Have you
considered using an action with a very high concurrency setting for your
problem? The usual issue with these persistent connections is, that
OpenWhisk (in concurrency: 1 mode) spawns a lot of containers that each
need a persistent connection. With the support for arbitrary concurrency we
should be able to heavily alleviate that and thus focus a lot of the
traffic to very few running actions. The connection can be shared inside a
single running action. I'm not convinced that you actually need an external
service here given the feature set we already have.

2. To Carlos' point with Websockets right into the container: The issue
here is, that Websockets workloads are not request/response (or at least
there is no way of knowing if they are). That completely breaks the scaling
model that OpenWhisk uses today. We measure the amount of in-flight
requests to the action. With websockets, there is no way of measuring (and
thus controlling) the amount of workload that's being pumped into a
container. That may very much be desirable for the workload at hand, but as
of today it's not a good fit for how OpenWhisk is build.

Cheers,
M

Am Di., 22. Jan. 2019 um 13:56 Uhr schrieb Michele Sciabarra <
michele@sciabarra.com>:

> Yes but if the patch is available it is possible to use an action runtime
> as an interim solution for providing a WebSocket server using a Kubernetes
> cluster.
>
> I did it because I am writing the chapter "messaging" of the book on
> OpenWhisk, and discovered that it is not recommended to use an action as a
> Kafka client as it can flood a Kafka server. So I implemented the
> recommended solution with a websocket server.
>
> I can, of course, provide a  solution as a separate, not official way of
> using  but the idea was to talk of the "OpenWhisk" recommended way in the
> book...
>
> --
>   Michele Sciabarra
>   michele@sciabarra.com
>
> ----- Original message -----
> From: Carlos Santana <csantana23@gmail.com>
> To: dev@openwhisk.apache.org
> Subject: Re: [Long] I implemented websocket support for the Golang and
> related runtimes:
> Date: Tue, 22 Jan 2019 07:03:32 -0500
>
> I think there are 2 features here
>
> 1. Re use an action as is to be injected into a runtime that supports the
> websocket
>
> 2. Have OpenWhisk gain improvements by the invoker communicating with with
> user container with a websocket stream vs a 1 http req /run. It might be
> useful to show the benefits in performance specially when multiconcurrency
> is enable meaning for example having 200 in flight http connections or a
> set pool vs using websocket transport to the user container. Maybe
> something for Tyson to give some thought if he sees benefits for the
> multiconcurrency
>
> For 2, I think it requires more discussions since without the invoker
> counter part it doesn’t make sense todo the runtime first, do them together
> to find the stable API contract for the user container via websocket.
>
> - Carlos Santana
> @csantanapr
>
> > On Jan 22, 2019, at 6:23 AM, Michele Sciabarra <michele@sciabarra.com>
> wrote:
> >
> > I guess then this feature is of interest and worth to be merged, as it
> provides a basis on the runtimes to implement websockets as a general
> feature then. Am I correct ? :)
> >
> >
> > --
> >  Michele Sciabarra
> >  michele@sciabarra.com
> >
> > ----- Original message -----
> > From: Carlos Santana <csantana23@gmail.com>
> > To: dev@openwhisk.apache.org
> > Subject: Re: [Long] I implemented websocket support for the Golang and
> related runtimes:
> > Date: Tue, 22 Jan 2019 05:49:39 -0500
> >
> > Thanks Michele for the clarification
> >
> > My knative remark was only about to scale to zero, meaning when there is
> times that no one is using my app no pod/container is running at all.
> >
> > The main.go code can still be loaded via ConfigMap in Knative or without
> in Kubernetes. It still uses the same image
> >
> >
> > - Carlos Santana
> > @csantanapr
> >
> >> On Jan 21, 2019, at 1:34 PM, Michele Sciabarra <michele@sciabarra.com>
> wrote:
> >>
> >> Actually YES this is exactly what I did.  A websocket that accept a
> websocket and writes in kafka.
> >>
> >> There is not yet a demo, but I am working on it. I am building a small
> webchat doing it.
> >>
> >> So far the demo is only this one https://hellows.sciabarra.net/ that
> uses the "hello.go" as an action turned in a websocket.
> >>
> >> If you use a websocket client you can see it is actually the action
> aswering in a websocket.
> >>
> >>> ws wss://hellows.sciabarra.net/hello
> >>> {"name":"Mike"}
> >> < {"golang-main-single":"Hello, Mike!"}
> >>
> >>> {}
> >> < {"golang-main-single":"Hello, world!"}
> >>
> >> You just need the action loop container modified and you can deploy an
> action in Kubernetes
> >>
> >> Yes this can be hooked in knative, but I did it simpler with an
> "autoinit".
> >> Code of the action is provided in a file through a configmap and then
> the runtime initialize the action instead of waiting a /init and serves it
> in a websocket.
> >>
> >> The deployment of the "https://hellows.sciabarra.net" is entirely here:
> >>
> >>
> https://github.com/sciabarracom/incubator-openwhisk-runtime-go/blob/websocket-support/examples/websocket-hello/hellows.yml
> >>
> >> The client is just a static html page.
> >>
> >> I can talk of this work wednesday if we can consider merging this
> feature.
> >>
> >> --
> >> Michele Sciabarra
> >> michele@sciabarra.com
> >>
> >> ----- Original message -----
> >> From: Carlos Santana <csantana23@gmail.com>
> >> To: dev@openwhisk.apache.org
> >> Subject: Re: [Long] I implemented websocket support for the Golang and
> related runtimes:
> >> Date: Mon, 21 Jan 2019 12:37:05 -0500
> >>
> >> Hi Michele this looks very cool in deed
> >>
> >> Where you able to create a container in k8s with a main.go that took
> >> websocket input and output to a persistent kafka connection
> >>
> >> I'm interested in this as I have a use case that I want IBM Cloud
> Function
> >> to ingest into kafka, and I was going to build similar thing as you did
> >> using http 1or 2 server, that then ingest into kafka as a service (Event
> >> Streams).
> >> I was going to deploy this container into kubernetes, but I wanted the
> >> container to scale down to zero using Knative.
> >>
> >> You have such main.go for your runtime with websocket at one side and
> kafka
> >> producer at the other?
> >>
> >> -- Carlos
> >>
> >> On Thu, Jan 17, 2019 at 1:07 PM Michele Sciabarra <
> michele@sciabarra.com>
> >> wrote:
> >>
> >>> Hello whiskers!
> >>>
> >>> Sorry it is a bit long, so I split it into parts with headlines.
> >>>
> >>> TL;DR
> >>>
> >>> I implemented support for Websocket so you can deploy an Action as a
> >>> WebSocket server if you have a Kubernetes cluster (or just a Docker
> >>> server). See at the end of this post for an example of a Kubernetes
> >>> deployment descriptor.
> >>>
> >>> Here is a very simple demo using it:
> >>>
> >>>   https://hellows.sciabarra.net/
> >>>
> >>> It uses a websocket server implemented using the golang runtime and the
> >>> code of an UNCHANGED OpenWhisk action. All the magic happens at
> deployment
> >>> using the descriptor provided.
> >>>
> >>> I believe it is a good foundation for implementing websocket support in
> >>> OpenWhisk. The next step would be to provide support at the API level.
> >>>
> >>> After reading the rest, the question is: does the community approve
> this
> >>> feature? If yes, I can submit a PR for including it in the next
> release of
> >>> the actionloop.
> >>>
> >>> 1. Motivation: why I did this
> >>>
> >>> A few days ago I asked what was the problem in having an action that
> >>> creates a persistent connection to Kafka. I was answered that a
> Serverless
> >>> environment can flood Kafka with requests because more actions are
> spawn
> >>> when the load increase.
> >>>
> >>> The solution is to create a separate server to be deployed somewhere,
> for
> >>> example, Kubernetes, maybe using WebSockets to communicate with Kafka.
> In
> >>> short, I had the need to transform an action in a WebSocket server.
> >>>
> >>> Hence I had the idea of adding WebSocket support to Action as WebSocket
> >>> server, adding support for WebSocket to ActionLoop, so I could create a
> >>> WebSocket server in the same way as you write an action.
> >>>
> >>> 2. What I did
> >>>
> >>> I implemented WebSocket support in the action runtime. If you deploy
> the
> >>> action now it answers not only to `/run` but also to `/ws` (it is
> >>> configurable) as a WebSocket in continuous mode.
> >>>
> >>> You enable the WebSocket setting the environment variable OW_WEBSOCKET.
> >>> Also, for the sake of easy deployment, there is also now an autoinit
> >>> feature. If you set the environment variable to OW_AUTOINIT, it will
> >>> initialize the runtime from the file you specified in the variable.
> >>>
> >>> Ok, fine you can say, but how can I use it?
> >>>
> >>> With a Kubernetes descriptor! You can launch the runtime in Kubernetes,
> >>> provide the main action in it (you can also download it from a git
> repo or
> >>> store in a volume), and now your action is a web socket server
> answering to
> >>> your requests.
> >>>
> >>> Look to the following descriptor for an example:
> >>>
> >>> It is a bit long, this is what it does
> >>>
> >>> - it creates a configmap containing the action code
> >>> - it launches the image mounting the action code
> >>> - the image initialize the action and then listen to the WebSocket
> >>> - the image also exposes the web socket using an ingress
> >>>
> >>>
> >>> apiVersion: v1
> >>> kind: Namespace
> >>> metadata:
> >>> name: hellows
> >>> ---
> >>> apiVersion: v1
> >>> kind: ConfigMap
> >>> metadata:
> >>> name: hellows
> >>> namespace: hellows
> >>> data:
> >>> main.go: |
> >>>   package main
> >>>   import "fmt"
> >>>   func Main(obj map[string]interface{}) map[string]interface{} {
> >>>     name, ok := obj["name"].(string)
> >>>     if !ok {
> >>>       name = "world"
> >>>     }
> >>>     fmt.Printf("name=%s\n", name)
> >>>     msg := make(map[string]interface{})
> >>>     msg["golang-main-single"] = "Hello, " + name + "!"
> >>>     return msg
> >>>   }
> >>> ---
> >>> apiVersion: v1
> >>> kind: Pod
> >>> metadata:
> >>> name: hellows
> >>> namespace: hellows
> >>> labels:
> >>>   app: hellows
> >>> spec:
> >>> volumes:
> >>> - name: mnt
> >>>   configMap:
> >>>     name: hellows
> >>> containers:
> >>> - name: hellows
> >>>   image: actionloop/golang-v1.11:ws3
> >>>   ports:
> >>>   - containerPort: 8080
> >>>     protocol: TCP
> >>>   volumeMounts:
> >>>   - name: mnt
> >>>     mountPath: "/mnt"
> >>>   env:
> >>>   - name: OW_WEBSOCKET
> >>>     value: /hello
> >>>   - name: OW_AUTOINIT
> >>>     value: /mnt/main.go
> >>> ---
> >>> apiVersion: v1
> >>> kind: Service
> >>> metadata:
> >>> name: hellows
> >>> namespace: hellows
> >>> spec:
> >>> ports:
> >>> - port: 8080
> >>>   protocol: TCP
> >>>   targetPort: 8080
> >>> selector:
> >>>   app: hellows
> >>> ---
> >>> apiVersion: extensions/v1beta1
> >>> kind: Ingress
> >>> metadata:
> >>> name: hellows
> >>> namespace: hellows
> >>> spec:
> >>> rules:
> >>> - host: hellows.sciabarra.net
> >>>   http:
> >>>     paths:
> >>>     - path: /hello
> >>>       backend:
> >>>         serviceName: hellows
> >>>         servicePort: 8080
> >>>
> >>>
> >>> --
> >>> Michele Sciabarra
> >>> michele@sciabarra.com
> >>>
> >>
> >>
> >> --
> >> Carlos Santana
> >> <csantana23@gmail.com>
>

Mime
View raw message