Skip to content

Commit

Permalink
reorganize halloumi by language
Browse files Browse the repository at this point in the history
  • Loading branch information
EvanBoyle committed Oct 17, 2020
1 parent c50453f commit 231f9ad
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 48 deletions.
3 changes: 0 additions & 3 deletions Makefile

This file was deleted.

74 changes: 36 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,41 @@ You write your application, we run it in the cloud.

## Summary

The halloumi SDK defines an application model where you simply write your http handler, and we take care of the rest:
The halloumi SDK defines an application model where you simply write your http handler, and we take care of the rest.

The [node](./nodejs) version is independently runnable via `yarn start`, and the [go](./go) version has a small binary CLI to orchestrate execution.

All you have to do is define HTTP handlers, and `halloumi` takes care of running it in the cloud:

### Node.js

```typescript
// this application will deploy multiple services publicly available int the cloud
const application = new App();

const svc1 = new WebService("hello", (expressApp: express.Express) => {
// a simple static handler
expressApp.get('/', (req, res) => res.send("omg i'm alive\n"));
});
application.addService(svc1);


const svc2 = new WebService("world", (expressApp: express.Express) => {
expressApp.get('/', async (req, res) => {
// track dependencies across services and make them available at runtime
const svc1Url = svc1.discover();
// this handler calls svc1 and passes the result through
const result = await (await fetch(svc1Url)).text()

res.send(`this is the world. With a window from hello:\n${result} \n`);
});
});
application.addService(svc2);

application.run().catch(err => { console.error(err) });
```

### Go

```go
app := app.NewApp("petStore")
Expand All @@ -28,21 +62,10 @@ randomNumberService := web.NewWebService("randomNumber", func() http.Handler {
app.Register(randomNumberService)
```

To deploy this app, simply run your program with the `halloumi` tool:

```shell
$ halloumi main.go
Deployming app petStore
Deploying service randomNumber
Successfully deployed service randomNumber
Service randomNumber running at: web-lb-f1f8017-934112424.us-west-2.elb.amazonaws.com
Successfully deployed app petStore
```
### Cross-service Dependencies
Halloumi allows consuming services from other services:

```go

// a cloud web service that returns N of a random animal.
// this service takes a dependency on the URLs of the previously defined services
nAnimalsService := web.NewWebService("nAnimals", func() http.Handler {
Expand Down Expand Up @@ -87,29 +110,4 @@ nAnimalsService := web.NewWebService("nAnimals", func() http.Handler {
r.HandleFunc("/", handler)
return r
})
```

## installation
1. Clone repo to $GOPATH
2. make (to install the halloumi tool)
3. run the included example `halloumi main.go`

## prereqs

1. authenticated pulumi CLI (>= v2.10.1)
2. AWS CLI + creds
3. Docker

## How does it work?
The halloumi orchestrator works off of the principal of invoking the program different sets of environment variables

1. First pass `DRY_RUN`: this procudes a list of apps and services to deploy allowing the program to exit without starting any http servers.
2. The orchestrator deploys each app and service, building a docker image from the provided `main.go` file.
3. When a service is deployed, an environment variable `HALLOUMI_APPNAME_SVCNAME` is set in the ECS task. When the program is run with that environment variable, the program will start a web server for the specified service.

## TODOs:
1. Can we get rid of the CLI? This demo would be more powerful without it.
2. Auto-generate the docker file side by side. Right now it is just checked in along side the example.
3. Add some other components besides web services (blob, queue, db).
4. Write an SDK for a language like javascript. The SDK layer is super thin and wouldn't be much work.
5. Perf/parallelism. Right now to be lazy, I don't detect dependencies and take advantage of the fact that declaration order is also dependency order. This just means that deployments are serial and slow.
```
4 changes: 2 additions & 2 deletions Dockerfile → go/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
FROM golang

# Copy the local package files to the container's workspace.
ADD . /go/src/github.com/pulumi/halloumi
ADD . /go/src/github.com/pulumi/halloumi/go

# Build the outyet command inside the container.
# (You may fetch or manage dependencies here,
# either manually or with a tool like "godep".)
WORKDIR /go/src/github.com/pulumi/halloumi
WORKDIR /go/src/github.com/pulumi/halloumi/go
RUN go build -o /go/bin/main

# Run the outyet command by default when the container starts.
Expand Down
3 changes: 3 additions & 0 deletions go/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build: install
install:
go install github.com/pulumi/halloumi/go/pkg/cmd/halloumi
115 changes: 115 additions & 0 deletions go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# halloumi

Pulumi + Heroku = Halloumi

You write your application, we run it in the cloud.

`halloumi` is a prototype and not under active development.

## Summary

The halloumi SDK defines an application model where you simply write your http handler, and we take care of the rest:

```go
app := app.NewApp("petStore")

// a cloud web service that returns a number [0-100)
randomNumberService := web.NewWebService("randomNumber", func() http.Handler {
// a normal HTTP handler, halloumi takes care of running this in the cloud
r := mux.NewRouter()
handler := func(w http.ResponseWriter, r *http.Request) {
rand.Seed(time.Now().UnixNano())
fmt.Fprintf(w, "%d", rand.Intn(100))
}
r.HandleFunc("/", handler)
return r
})

app.Register(randomNumberService)
```

To deploy this app, simply run your program with the `halloumi` tool:

```shell
$ halloumi main.go
Deployming app petStore
Deploying service randomNumber
Successfully deployed service randomNumber
Service randomNumber running at: web-lb-f1f8017-934112424.us-west-2.elb.amazonaws.com
Successfully deployed app petStore
```
### Cross-service Dependencies
Halloumi allows consuming services from other services:

```go

// a cloud web service that returns N of a random animal.
// this service takes a dependency on the URLs of the previously defined services
nAnimalsService := web.NewWebService("nAnimals", func() http.Handler {
r := mux.NewRouter()
var num string
var animal string
handler := func(w http.ResponseWriter, r *http.Request) {
// Notice how we have the URL of randomNumberService
// available to consume here!
numResp, err := http.Get(randomNumberService.URL())
if err != nil {
fmt.Fprintf(w, err.Error())
}
defer numResp.Body.Close()

if numResp.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(numResp.Body)
if err != nil {
log.Fatal(err)
}
num = string(bodyBytes)
}

// Notice how we have the URL of randomAnimalService
// available to consume here!
animalResp, err := http.Get(randomAnimalService.URL())
if err != nil {
fmt.Fprintf(w, err.Error())
}
defer numResp.Body.Close()

if animalResp.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(animalResp.Body)
if err != nil {
log.Fatal(err)
}
animal = string(bodyBytes)
}

fmt.Fprintf(w, "Wow, you got %s %ss!", num, animal)
}
r.HandleFunc("/", handler)
return r
})
```

## installation
1. Clone repo to $GOPATH
2. make (from this directory to install the halloumi tool)
3. run the included example `halloumi main.go`

## prereqs

1. authenticated pulumi CLI (>= v2.10.1)
2. AWS CLI + creds
3. Docker

## How does it work?
The halloumi orchestrator works off of the principal of invoking the program different sets of environment variables

1. First pass `DRY_RUN`: this procudes a list of apps and services to deploy allowing the program to exit without starting any http servers.
2. The orchestrator deploys each app and service, building a docker image from the provided `main.go` file.
3. When a service is deployed, an environment variable `HALLOUMI_APPNAME_SVCNAME` is set in the ECS task. When the program is run with that environment variable, the program will start a web server for the specified service.

## TODOs:
1. Can we get rid of the CLI? This demo would be more powerful without it.
2. Auto-generate the docker file side by side. Right now it is just checked in along side the example.
3. Add some other components besides web services (blob, queue, db).
4. Write an SDK for a language like javascript. The SDK layer is super thin and wouldn't be much work.
5. Perf/parallelism. Right now to be lazy, I don't detect dependencies and take advantage of the fact that declaration order is also dependency order. This just means that deployments are serial and slow.
2 changes: 1 addition & 1 deletion go.mod → go/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/pulumi/halloumi
module github.com/pulumi/halloumi/go

go 1.14

Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions main.go → go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
petname "github.com/dustinkirkland/golang-petname"
"github.com/gorilla/mux"
"github.com/prometheus/common/log"
"github.com/pulumi/halloumi/sdk/app"
"github.com/pulumi/halloumi/sdk/web"
"github.com/pulumi/halloumi/go/sdk/app"
"github.com/pulumi/halloumi/go/sdk/web"
)

func main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"os"

"github.com/pkg/errors"
"github.com/pulumi/halloumi/pkg/orchestrator"
"github.com/pulumi/halloumi/go/pkg/orchestrator"
"github.com/spf13/cobra"
)

Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion sdk/app/app.go → go/sdk/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net/http"
"os"

"github.com/pulumi/halloumi/sdk/web"
"github.com/pulumi/halloumi/go/sdk/web"
)

type App struct {
Expand Down
File renamed without changes.
File renamed without changes.

0 comments on commit 231f9ad

Please sign in to comment.