Coder Social home page Coder Social logo

syumai / workers Goto Github PK

View Code? Open in Web Editor NEW
637.0 8.0 39.0 333 KB

Go package to run an HTTP server on Cloudflare Workers.

License: MIT License

Go 62.25% Makefile 3.16% JavaScript 33.74% HTML 0.47% Shell 0.38%
cloudflare cloudflare-workers go golang

workers's Issues

Cannot build wasm binary

using template

$ make dev
wrangler dev
 ⛅️ wrangler 2.1.15 (update available 2.2.1)
------------------------------------------------------
Running custom build: make build
make[1]: Entering directory '/home/arman/Go-Workspace/rapidapi-translate'
mkdir -p dist
tinygo build -o ./dist/app.wasm -target wasm ./...
# encoding/xml
/usr/lib/go-1.19/src/encoding/xml/typeinfo.go:318:14: typ.FieldByIndex undefined (type reflect.Type has no field or method FieldByIndex)
/usr/lib/go-1.19/src/encoding/xml/typeinfo.go:319:14: typ.FieldByIndex undefined (type reflect.Type has no field or method FieldByIndex)
make[1]: *** [Makefile:8: build] Error 1
make[1]: Leaving directory '/home/arman/Go-Workspace/rapidapi-translate'

✘ [ERROR] Command failed with exit code 2: make build


If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose
make: *** [Makefile:3: dev] Error 1

Fresh worker-go project not working

Description

I created a fresh new project with Golang. I followed the guide https://github.com/syumai/workers/tree/main/_templates/cloudflare/worker-go#getting-started-1. Make dev and make build command are executed without any errors, but when I try to acces the localhost, where the worker is hosted, I get an error.
WebAssembly.Instance(): Import #0 module="gojs": module is not an object or function.

image

Versions

  • Go: 1.21.1
  • Node: 20.8.0 (even though I tried v16 and v18)

Deadlock reading from R2 and writing to a ZIP writer

Hi,

I'm trying to stream ZIP file that is dynamically created on the fly. The implementation already works (not in tinygo, but in full go), but it exhibits a panic at runtime. Here is the error as captured by wrangler:

POST http://127.0.0.1:9899/services/stream-zip-from-r2 - Exception Thrown @ 4/16/2024, 6:54:17 PM
  (log) fatal error: all goroutines are asleep - deadlock!
  (log) 
  (log) goroutine 1 [chan receive]:
  (log) github.com/syumai/workers.Serve(...)
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/handler.go:95
  (log) main.main()
  (log)         /Users/elie/Projects/workers-go/main.go:164 +0x1c
  (log) 
  (log) goroutine 6 [select]:
  (log) io.(*pipe).read(0x18c8ba0, {0x1bec800, 0x4100, 0x4100})
  (log)         /usr/local/go/src/io/pipe.go:57 +0x6
  (log) io.(*PipeReader).Read(0x18c8ba0, {0x1bec800, 0x4100, 0x4100})
  (log)         /usr/local/go/src/io/pipe.go:134 +0x4
  (log) github.com/syumai/workers/internal/jsutil.(*readerToReadableStream).Pull(0x1bb0300, {{}, 0x7ff800010000009d, 0x1ba3588})
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/internal/jsutil/stream.go:121 +0x6
  (log) github.com/syumai/workers/internal/jsutil.ConvertReaderToReadableStream.func1.1({{}, 0x0, 0x0}, {0x1b94360, 0x2, 0x2})
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/internal/jsutil/stream.go:170 +0x5
  (log) syscall/js.handleEvent()
  (log)         /usr/local/go/src/syscall/js/func.go:100 +0x23
  (log) syscall/js.Value.New({{}, 0x7ff800040000000f, 0x180c068}, {0x1841e38, 0x1, 0x1})
  (log)         /usr/local/go/src/syscall/js/js.go:431 +0x3
  (log) github.com/syumai/workers/internal/jsutil.NewPromise(...)
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/internal/jsutil/jsutil.go:34
  (log) github.com/syumai/workers/internal/jsutil.ConvertReaderToReadableStream.func1({{}, 0x7ff8000100000098, 0x1ba3578}, {0x1bc8b60, 0x1, 0x1})
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/internal/jsutil/stream.go:178 +0xd
  (log) syscall/js.handleEvent()
  (log)         /usr/local/go/src/syscall/js/func.go:100 +0x23
  (log) 
  (log) goroutine 8 [select]:
  (log) github.com/syumai/workers/internal/jsutil.(*readableStreamToReadCloser).Read(0x1b5a000, {0x1a3c000, 0x8000, 0x8000})
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/internal/jsutil/stream.go:61 +0x22
  (log) io.copyBuffer({0x134828, 0x1b84000}, {0x134e00, 0x1bc8730}, {0x0, 0x0, 0x0})
  (log)         /usr/local/go/src/io/io.go:429 +0x27
  (log) io.Copy(...)
  (log)         /usr/local/go/src/io/io.go:388
  (log) github.com/syumai/workers/internal/jsutil.(*readableStreamToReadCloser).WriteTo(0x1b5a000, {0x134828, 0x1b84000})
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/internal/jsutil/stream.go:96 +0xc
  (log) io.copyBuffer({0x134828, 0x1b84000}, {0x134e20, 0x1b5a000}, {0x1bf1000, 0x4100, 0x4100})
  (log)         /usr/local/go/src/io/io.go:411 +0x22
  (log) io.CopyBuffer({0x134828, 0x1b84000}, {0x134e20, 0x1b5a000}, {0x1bf1000, 0x4100, 0x4100})
  (log)         /usr/local/go/src/io/io.go:402 +0x4
  (log) main.main.func2({0x138618, 0x1ba5400})
  (log)         /Users/elie/Projects/workers-go/main.go:104 +0xa1
  (log) github.com/labstack/echo/v4.(*Echo).add.func1({0x138618, 0x1ba5400})
  (log)         /Users/elie/go/pkg/mod/github.com/labstack/echo/[email protected]/echo.go:582 +0x5
  (log) github.com/labstack/echo/v4.(*Echo).ServeHTTP(0x18c4908, {0x135e40, 0x1b84e10}, 0x1b8ed80)
  (log)         /Users/elie/go/pkg/mod/github.com/labstack/echo/[email protected]/echo.go:669 +0x52
  (log) github.com/syumai/workers.handleRequest.func1()
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/handler.go:77 +0x4
  (log) created by github.com/syumai/workers.handleRequest in goroutine 7
  (log)         /Users/elie/go/pkg/mod/github.com/syumai/[email protected]/handler.go:74 +0x28
  (warn) exit code: 2
✘ [ERROR]   TypeError: Cannot read properties of undefined (reading 'exports')

Here is the implementation of a simple streaming ZIP:

e.POST("/services/stream-zip-from-r2", func(c echo.Context) error {
	// Get the request
	req := struct {
		BucketName  string `json:"bucketName" validate:"required,oneof=expense-documents profile-photos"`
		ZipFileName string `json:"zipFileName" validate:"required,min=1"`

		Files []struct {
			FileName string `json:"name" validate:"required,min=1"`
			FileURL  string `json:"url" validate:"required,min=1"`
		} `json:"files" validate:"required,dive"`

		Relaxed bool `json:"relaxed"` // Don't stop ZIP creation if a file is not found
	}{}
	if _, err := ValidateBodyStrictInto(c.Request().Body, &req); err != nil {
		return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
	}

	// Get the bucket binding
	bucket, err := getBucketBinding(c.Request().Context(), req.BucketName)
	if err != nil {
		return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()})
	}

	// Start streaming
	c.Response().Header().Set(echo.HeaderContentType, "application/zip")
	c.Response().Header().Set(echo.HeaderContentDisposition, "attachment; filename="+req.ZipFileName)
	c.Response().WriteHeader(http.StatusOK)

	// Prepare to stream a ZIP file from R2
	writer := zip.NewWriter(c.Response())
	writer.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
		return flate.NewWriter(out, flate.NoCompression)
	})
	//defer func(writer *zip.Writer) {
	//	if err := writer.Close(); err != nil {
	//		c.Logger().Errorf("failed to close ZIP writer: %v", err)
	//	}
	//}(writer)

	count := 0
	for _, file := range req.Files {
		// Get the file from R2
		reader, err := bucket.Get(file.FileURL)
		if err != nil {
			c.Logger().Errorf("failed to get file '%s' from R2: %v", file.FileName, err)
			return err
		}
		if reader == nil {
			if req.Relaxed {
				c.Logger().Warnf("file '%s' not found", file.FileURL)
				continue
			} else {
				c.Logger().Errorf("file '%s' not found", file.FileURL)
				return fmt.Errorf("file '%s' not found", file.FileURL)
			}
		}
		// no need to close the reader

		// Add the file to the ZIP
		writer, err := writer.Create(file.FileName)
		if err != nil {
			c.Logger().Errorf("failed to create file '%s' in ZIP: %v", file.FileName, err)
			return err
		}
		c.Logger().Infof("Streaming file '%s' to ZIP (length = %d bytes)", file.FileName, reader.Size)

		// Stream the file
		blob := make([]byte, reader.Size)
		if _, err := io.ReadFull(reader.Body, blob); err != nil {
			c.Logger().Errorf("failed to read file '%s' from R2: %v", file.FileName, err)
			return err
		}
		if _, err := writer.Write(blob); err != nil {
			c.Logger().Errorf("failed to write file '%s' to ZIP: %v", file.FileName, err)
			return err
		}

		// This causes a quick deadlock
		//if _, err := io.CopyBuffer(writer, reader.Body, make([]byte, 16_640)); err != nil {
		//	c.Logger().Errorf("failed to write file '%s' to ZIP: %v", file.FileName, err)
		//	return err
		//}

		count++
	}

	return nil
})

Is this a known issue, or am I doing something wrong? Note: the defer to close the writer doesn't have any effect, it crashes all the same.

Another note: I have create a test route that will just generate random string and ZIP it (just store, no compression), and that one had no panic. So, I'm not sure if this is an R2 read?

Thank you.

Remove dependencies on Context

#84 introduced new internal feature, jsutil.RuntimeContext.
This feature allows most Context-dependent functions to be fixed as follows.

Before

func Getenv(ctx context.Context, name string) string

After

func Getenv(name string) string

The change adds flexibility to Go programs using workers.

This will be breaking change.

Error: write EPIPE when using wrangler dev to run cloudflare worker using itty-router

Issue

When I do what the quick start says, I get the following error when I run make dev

My Environment

  • Ubuntu 22.04.2 LTS (GNU/Linux 5.15.90.1-microsoft-standard-WSL2 x86_64)

Error

❯ make dev
wrangler dev
 ⛅️ wrangler 3.0.1
------------------
wrangler dev now uses local mode by default, powered by 🔥 Miniflare and 👷 workerd.
To run an edge preview session for your Worker, use wrangler dev --remote
Running custom build: make build
make[1]: Entering directory '/home/zztkm/dev/github.com/pistachiostudio/hello-api'
go run github.com/syumai/workers/cmd/workers-assets-gen@latest
tinygo build -o ./build/app.wasm -target wasm ./...
make[1]: Leaving directory '/home/zztkm/dev/github.com/pistachiostudio/hello-api'
⎔ Starting local server...
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit                                                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
/usr/local/lib/node_modules/wrangler/wrangler-dist/cli.js:30632
            throw a;
            ^

Error: write EPIPE
    at afterWriteDispatched (node:internal/stream_base_commons:160:15)
    at writeGeneric (node:internal/stream_base_commons:151:3)
    at Socket._writeGeneric (node:net:917:11)
    at Socket._write (node:net:929:8)
    at writeOrBuffer (node:internal/streams/writable:392:12)
    at _write (node:internal/streams/writable:333:10)
    at Writable.write (node:internal/streams/writable:337:10)
    at Runtime.updateConfig (/usr/local/lib/node_modules/wrangler/node_modules/miniflare/dist/src/index.js:5120:26)
    at async #assembleAndUpdateConfig (/usr/local/lib/node_modules/wrangler/node_modules/miniflare/dist/src/index.js:9130:23)
    at async #init (/usr/local/lib/node_modules/wrangler/node_modules/miniflare/dist/src/index.js:8894:5)
Emitted 'error' event on Socket instance at:
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  errno: -32,
  code: 'EPIPE',
  syscall: 'write'
}

Node.js v18.12.1
make: *** [Makefile:3: dev] Error 7

Solution

I was able to solve the problem by installing libc++1.

apt install libc++1

refs: https://stackoverflow.com/questions/76281931/error-write-epipe-when-using-wrangler-dev-to-run-cloudflare-worker-using-itty-r

Can export NewObject and AwaitPromise functions?

Can export NewObject and AwaitPromise functions? I try to impl workers AI by myself, but i must use linkname to call these functions.

type AI struct {
	instance js.Value
}

func NewAI() *AI {
	return &AI{
		instance: cloudflare.GetBinding("AI"),
	}
}

func (a *AI) Translate(opts TranslateOptions) (string, error) {
	p := a.instance.Call("run", "@cf/meta/m2m100-1.2b", opts.toJS())

	t, err := AwaitPromise(p)
	if err != nil {
		return "", err
	}

	return t.Get("translated_text").String(), nil
}


//go:linkname NewObject github.com/syumai/workers/internal/jsutil.NewObject
func NewObject() js.Value

//go:linkname AwaitPromise github.com/syumai/workers/internal/jsutil.AwaitPromise
func AwaitPromise(promiseVal js.Value) (js.Value, error)

Write Durable Objects in Go

Hi,

First of all, I'd like to express my thanks and my encouragement for the folks behind this project. I think this deserve full support from Cloudflare.

Now, I seem to have noticed that the Durable Objects can only be written in JS. I'd like to know if there is a plan to support writing actual DurableObject classes using Go itself, and not just the ability to call the stub from Go.

Thank you.

Can fetch pkg support streaming?

When requesting a large file, it will cause err: failed on promise: TypeError: Memory limit would be exceeded before EOF.

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		fetchReq, err := fetch.NewRequest(req.Context(), http.MethodGet, "http://lg.hkg.hosthatch.com/1GB.test", nil)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		resp, err := fetch.NewClient().Do(fetchReq, nil)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "err: %v", err)
			return
		}
		defer resp.Body.Close()
		io.Copy(w, resp.Body)
	})
	workers.Serve(nil)
}

Unable to get accurate date/time

When getting the current time with time.Now() we get back incorrect time. I assume this is because tinygo isn't accessing the system clock properly.

Could it be possible to have some function which gets the date and time from the JavaScript side of things?

Error with Fetch returning 204 No Content response

Hi!
Testing with fetch example
Just change for example: (reqres.in)

r, err := fetch.NewRequest(req.Context(), http.MethodDelete, "https://reqres.in/api/users/1", nil)

Get an error

panic: syscall/js: call of Value.Call on null
X [ERROR] A hanging Promise was canceled. This happens when the worker runtime is waiting for a Promise from JavaScript to resolve, but has detected that the Promise cannot possibly ever resolve because all code and events related to the Promise's I/O context have already finished.

[wrangler:inf] GET / 500 Internal Server Error (252ms)                                    
X [ERROR] Uncaught (in response) Error: The script will never generate a response.

Also checked with the GitHub API

Frequent "Promise will never complete" and "call to released function" errors in the fetch example

Hey.
I'm running the fetch example (_examples/fetch/main.go) under a free worker plan. When making about 2-3 requests per second the example works quite well, however, when the request rate increases to about 5 request per second the example starts to run into these errors:

...
GET https://first.hzgl.workers.dev/fetchexample - Ok @ 5/20/2023, 6:03:26 PM
GET https://first.hzgl.workers.dev/fetchexample - Exception Thrown @ 5/20/2023, 6:03:26 PM
✘ [ERROR]   Error: The script will never generate a response.
GET https://first.hzgl.workers.dev/fetchexample - Exception Thrown @ 5/20/2023, 6:03:26 PM
  (error) call to released function
✘ [ERROR]   Error: Promise will never complete.
GET https://first.hzgl.workers.dev/fetchexample - Ok @ 5/20/2023, 6:03:26 PM
...

Websocket support

Using package github.com/gorilla/websocket to server websocket connection.
When call upgrader.Upgrade(w, r, nil), it return an error:

2024/04/10 21:16:42 failed to upgrade websocket: websocket: response does not implement http.Hijacker

It seems that the response need to implement http.Hijacker interface.

connect() Socket API undefined

Raising this as I debug in parallel.

Summary: It appears that the attempt to get a handler on the connect method fails and returns undefined: https://github.com/syumai/workers/blob/main/cloudflare/sockets/connect.go#L33 -> https://github.com/syumai/workers/blob/main/internal/runtimecontext/context.go#L34

  • I originally ran into this when using a custom Dialer implementation to have lib/pq talk to Hyperdrive, and pq would return the below and fail to actually establish a TCP connection:
  • From looking at the source of runtimecontext I suspected I needed to plumb through a context.Context, but from the example below that doesn't seem to change anything here.
  • What am I missing?
# This is from https://github.com/syumai/workers/blob/main/internal/runtimecontext/context.go#L34
  (log) 2024/04/15 16:43:11 query failed: &errors.errorString{s:"pq: unexpected error: \"runtime object was not found\""}

Distilling this down into the minimal repro (below) I see this:

✘ [ERROR]   TypeError: Cannot read properties of undefined (reading 'exports')
package main

import (
	"net/http"
	"github.com/syumai/workers"
	"github.com/syumai/workers/cloudflare/sockets"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		msg := "Hello!"
		w.Write([]byte(msg))
	})
	// We pass the request context into `sockets.Connect` here
	http.HandleFunc("/dial", func(w http.ResponseWriter, r *http.Request) {
		sockets.Connect(r.Context(), "blog.questionable.services:80", &sockets.SocketOptions{SecureTransport: sockets.SecureTransportOff})
	})

	workers.Serve(nil) // use http.DefaultServeMux
}

Occasional panic in cloudflare/fetch.NewIncomingProperties()

I'm seeing an occasional panic triggered in NewIncomingProperties due to the cf object sometimes not including an asn attr.

Here are the relevant bits of a log entry:

      "stack": "RuntimeError: unreachable\n    at main.runtime._panic (wasm://wasm/main-0021d66a:wasm-function[27]:0x3833)\n    at main.github.com/syumai/workers/cloudflare/fetch.NewIncomingProperties (wasm://wasm/main-0021d66a:wasm-function[273]:0x6d6e8)\n    at main.main.handleRequest (wasm://wasm/main-0021d66a:wasm-function[130]:0x3388d)\n    at main.github.com/syumai/workers.handleRequest$1$gowrapper (wasm://wasm/main-0021d66a:wasm-function[268]:0x69041)\n    at main.tinygo_rewind (wasm://wasm/main-0021d66a:wasm-function[19]:0x651)\n    at main.resume.command_export (wasm://wasm/main-0021d66a:wasm-function[302]:0x78648)\n    at global.Go._resume (worker.js:470:26)\n    at worker.js:480:12\n    at new Promise (<anonymous>)\n    at syscall/js.valueNew (worker.js:362:44)",
      "name": "Error",
      "message": "unreachable",
      "timestamp": 1722244377174
    }
  ],
  "logs": [
    {
      "message": [
        "panic: syscall/js: call of Value.Int on undefined"
      ],
...
      "cf": {
        "clientTcpRtt": 101,
        "longitude": "3.39030",
        "httpProtocol": "HTTP/2",
        "tlsCipher": "AEAD-AES128-GCM-SHA256",
        "continent": "AF",
        "clientAcceptEncoding": "gzip, deflate, br, zstd",
        "country": "NG",
        "tlsClientAuth": {
          ...
        },
        "tlsExportedAuthenticator": {
          ...
        },
        "tlsClientHelloLength": "585",
        "colo": "LHR",
        "timezone": "Africa/Lagos",
        "verifiedBotCategory": "",
        "edgeRequestKeepAliveStatus": 1,
        "requestPriority": "weight=256;exclusive=1",
        "tlsClientExtensionsSha1": "NvNr7OneGURecm6A+SxDAGU5YHs=",
        "tlsVersion": "TLSv1.3",
        "region": "Lagos",
        "regionCode": "LA",
        "city": "Lagos",
        "latitude": "6.44740",
        "tlsClientRandom": "OunCfJXpHRkwcmMKYsDVSGckSnmYkjjW7hcH3MHkCCI="
      }

Notice the lack of an asn field.

I believe the code here:

Asn: cf.Get("asn").Int(),
needs to have a check around syscall/js.Value.IsUndefined().

JavaScript error: The 'credentials' field on 'RequestInitializerDict' is not implemented."

Hi @syumai , Thank you for building this great repository!

I try to deploy this tool to Cloudflare Pages.

When I want to deploy my repository into pages, I got this issue JavaScript error: The 'credentials' field on 'RequestInitializerDict' is not implemented." in my local and remote pages ENV.

I search this error, like this issue, seems the Cloudflare Workers add the credentials automatically, Do you know how to disable it? Or can we manually deploy it to pages without use wrangler.

Can you help to check it? Thank you!

Using "html/template"

Hi
I try to use templates, but got error
Is this supported ?
Thanks

import (
	...
	"html/template"
)

func main() {
	http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		tmpl, _ := template.New("foo").Parse(`<div>{{.CounterValue}}</div>`)

		data := map[string]int{
			"CounterValue": 10,
		}
		_ = tmpl.ExecuteTemplate(w, "foo", data)
	})
	workers.Serve(nil)
}

2024-01-20 122112

A HandlerFunc without writing a response body causes weird error

  • A HandlerFunc without writing response body causes weird error.
  • This issue was originally reported in #100 .
func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		// doing nothing here causes weird error
	})
	workers.Serve(nil) // use http.DefaultServeMux
}
$ curl localhost:8787
TypeError: Cannot read properties of undefined (reading 'exports')
    at syscall/js.valueNew (file:///home/syumai/go/src/github.com/syumai/workers-playground/syumai-workers-repro-issue-100/build/wasm_exec.js:395:24)
    at [object Object]
    at [object Object]
    at [object Object]
    at [object Object]
    at [object Object]
    at globalThis.Go._resume (file:///home/syumai/go/src/github.com/syumai/workers-playground/syumai-workers-repro-issue-100/build/wasm_exec.js:553:23)
    at Object.handleRequest (file:///home/syumai/go/src/github.com/syumai/workers-playground/syumai-workers-repro-issue-100/build/wasm_exec.js:564:8)
    at Object.fetch (file:///home/syumai/go/src/github.com/syumai/workers-playground/syumai-workers-repro-issue-100/build/shim.mjs:51:18)
    at async jsonError (file:///home/syumai/.nvm/versions/node/v20.12.2/lib/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts:22:10)

How to reproduce

Run How to reproduce steps in the repository below.

https://github.com/syumai/workers-playground/tree/main/syumai-workers-repro-issue-100

rename workers-assets-gen command to workers-cli and add init command

  • rename current workers-assets-gen command to workers-cli.
  • split generate command for asset generation.
  • add init command for initialize current Go application as Cloudflare Workers' application.

Error deploying with Terraform

I'm trying to get this (Very helpful! Thank you!) package to integrate with a Terraform workflow, instead of deploying using wrangler publish.

Here's what I've managed to get so far:

resource "terraform_data" "build" {
  # Changes to *.go files requires re-building it.
  input = {
    # https://stackoverflow.com/questions/51138667/can-terraform-watch-a-directory-for-changes
    dir_sha1 = sha1(join("", [for f in fileset("${path.module}", "*.go") : filesha1("${path.module}/${f}")]))
  }

  provisioner "local-exec" {
    command = <<EOC
go run github.com/syumai/workers/cmd/[email protected] -mode=go
GOOS=js GOARCH=wasm go build -o ./build/app.wasm .
EOC
  }
}

resource "cloudflare_worker_script" "script" {
  depends_on = [terraform_data.build]
  account_id = var.cloudflare_account_id
  name       = var.name
  content    = file("${path.module}/build/worker.mjs")

  // │ Error: error creating worker script: Wasm and blob bindings are not supported with modules; use imports instead (10021)
  module = false

  webassembly_binding {
    name   = "WASM"
    module = filebase64("./build/app.wasm")
  }
}

Refs:

This basically says "run the script to build app.wasm, then deploy the worker script with it as a binding". There's some quirks I still need to work out with TF lifecycle to ensure it builds before trying to take the filebase64, but that's not the bug I'm currently hitting.

The bug I'm hitting is that, whether or not I use the local-exec trick, deploying the script fails with:

╷
│ Error: error creating worker script: Uncaught SyntaxError: Cannot use import statement outside a module
│   at worker.js:1
│  (10021)
│ 
│   with cloudflare_worker_script.script,
│   on main.tf line 18, in resource "cloudflare_worker_script" "script":
│   18: resource "cloudflare_worker_script" "script" {
│ 

Digging around, it might be the case that the TF provider just doesn't support WASM workers, even though it claims to: cloudflare/terraform-provider-cloudflare#2039

I guess I'm opening this in case anybody's gotten this to work with this package, or understands the error message well enough to give any hints about what might be happening.

fetching a binary file returns a corrupted body

Hi! I'm using the fetch.NewRequest to build a proxy and serve files from a remote server, but non-text files are getting corrupted. The logs show the following warning:

Called .text() on an HTTP body which does not appear to be text. The body's Content-Type is "image/png". The result will probably be corrupted. Consider checking the Content-Type header before interpreting entities as text.

I was able to make it work by implementing my own toResponse function where I read the data from the blob.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.