Skip to content

Http Get example OOM #39

@damongolding

Description

@damongolding

The Http Get example on my Seeed Studio XIAO ESP32C3 will eventually hit a out of memory error, roughly around the 8 min mark for me.

I have had some success by calling runtime.GC() at the beginning and end of the loop but I am unsure if this is the best way to combat the underlining issue.

// This example gets an URL using http.Get().  URL scheme can be http or https.
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"runtime"
	"strings"
	"time"

	"tinygo.org/x/drivers/netdev"
	nl "tinygo.org/x/drivers/netlink"
	link "tinygo.org/x/espradio/netlink"
)

var (
	ssid     string
	password string
)

type ResponseData struct {
	Args    map[string]string `json:"args"`
	Headers map[string]string `json:"headers"`
	Origin  string            `json:"origin"`
	URL     string            `json:"url"`
}

func main() {
	// wait a bit for serial
	time.Sleep(2 * time.Second)

	link := link.Esplink{}
	netdev.UseNetdev(&link)

	println("Connecting to WiFi...")
	err := link.NetConnect(&nl.ConnectParams{
		Ssid:       ssid,
		Passphrase: password,
	})
	if err != nil {
		failure("WiFi connect failed: " + err.Error())
	}

	println("Connected. Getting URL...")
	name := "John Doe"
	occupation := "gardener"

	params := "name=" + url.QueryEscape(name) + "&" +
		"occupation=" + url.QueryEscape(occupation)

	path := fmt.Sprintf("http://httpbin.org/get?%s", params)

	d := &ResponseData{}

	cnt := 0
	for {
		runtime.GC()
		fmt.Printf("Getting %s\r\n\r\n", path)
		resp, err := http.Get(path)
		if err != nil {
			fmt.Printf("problem is %s\r\n", err.Error())
			time.Sleep(10 * time.Second)
			continue
		}

		fmt.Printf("%s %s\r\n", resp.Proto, resp.Status)
		for k, v := range resp.Header {
			fmt.Printf("%s: %s\r\n", k, strings.Join(v, " "))
		}
		fmt.Printf("\r\n")

		body, err := io.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s\r\n", err.Error())
			time.Sleep(10 * time.Second)
			continue
		}

		resp.Body.Close()

		err = json.Unmarshal(body, d)
		if err != nil {
			fmt.Printf("failed to unmarshal: %s\r\n", err.Error())
			time.Sleep(10 * time.Second)
			continue
		}

		fmt.Printf("args: %v\n", d.Args)
		fmt.Printf("headers: %v\n", d.Headers)
		fmt.Printf("origin: %s\n", d.Origin)
		fmt.Printf("url: %s\n", d.URL)

		cnt++
		fmt.Printf("-------- %d --------\r\n", cnt)
		runtime.GC()
		time.Sleep(10 * time.Second)
	}
}

func failure(msg string) {
	for {
		println("failure:", msg)
		time.Sleep(1 * time.Second)
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions