Skip to content

Http Get example OOM #39

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions