Using GoFiber to run an HTTP service. Running this code in the terminal on a Linux machine results in the GC working correctly and the memory being freed. Running it on FreeBSD as a startup service, the memory does not free, and leaks.
import (
"bytes"
"fmt"
"runtime"
"github.com/valyala/fastjson"
"github.com/xuri/excelize/v2"
)
func convert_json_to_excel(request_data *fastjson.Value, buffer_pointer *bytes.Buffer) error {
var err error
// Remove redundant "data" key passed from body
json_values := request_data.Get("data")
if json_values == nil {
err = fmt.Errorf("submitted json body must contain desired excel data in a key named \"data\": %d", err)
fmt.Println(err)
return err
}
json_values_array, _ := json_values.Array()
// Initial no longer needed
json_values.Del("data")
// Create a working temporary Excel "file"
excel_file := excelize.NewFile()
defer excel_file.Close()
sheet_index, _ := excel_file.NewSheet("Sheet1")
excel_file.SetActiveSheet(sheet_index)
//Embolden the first row
header_style, _ := excel_file.NewStyle(&excelize.Style{
Font: &excelize.Font{
Bold: true,
},
})
header_row_opts := excelize.RowOpts{StyleID: header_style}
stream_writer, _ := excel_file.NewStreamWriter("Sheet1")
// Widen all used columns based on headers
header_row, _ := json_values_array[0].Array()
stream_writer.SetColWidth(1, len(header_row), 30)
// Iterate through data and write to file
for row := 0; row < len(json_values_array); row++ {
active_row, _ := json_values_array[row].Array()
//fmt.Printf("%s\n", active_row)
// Streamwriter is very performant, use of it requires type []interface{}
interface_row := make([]interface{}, len(active_row))
for cell := 0; cell < len(active_row); cell++ {
// Free working memory
json_values_array[row].Del(fmt.Sprintf("%d", cell))
interface_row[cell] = active_row[cell].Get().MarshalTo(nil)
}
first_cell := fmt.Sprintf("A%d", (row + 1))
if row == 0 {
stream_writer.SetRow(first_cell, interface_row, header_row_opts)
} else {
stream_writer.SetRow(first_cell, interface_row)
}
}
stream_writer.Flush()
_, err = excel_file.WriteTo(buffer_pointer)
if err != nil {
err = fmt.Errorf("write fail: %d", err)
fmt.Println(err)
return err
}
// Force GC
runtime.GC()
return nil
}