From 9349ab95fc91f74f2c242a7e3ccc0b630c3d95f3 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sat, 11 Jan 2025 02:44:21 -0600 Subject: [PATCH] small app works, example core dumps on Marshal() --- Makefile | 2 +- addMutex.go | 15 ++++++++---- example/Makefile | 4 ++-- example/main.go | 58 ++++++++++++++------------------------------ small/Makefile | 49 +++++++++++++++++++++++++++++++++++++ small/fruit.New.go | 9 +++++++ small/fruit.proto | 20 ++++++++++++++++ small/main.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++ sort.go | 12 ++++------ sortFunc.go | 18 +++++++------- sortNew.go | 10 ++++---- 11 files changed, 188 insertions(+), 69 deletions(-) create mode 100644 small/Makefile create mode 100644 small/fruit.New.go create mode 100644 small/fruit.proto create mode 100644 small/main.go diff --git a/Makefile b/Makefile index 068d8a1..2b9bb7d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ BUILDTIME = $(shell date +%Y.%m.%d_%H%M) simple: build # make -C example clean simpleMutexGlobal goimports vet - make -C example clean simpleMutexProtoc goimports vet + # make -C example clean simpleMutexProtoc goimports vet full: install clean auto goimports vet build test install @echo everything worked and the example ran diff --git a/addMutex.go b/addMutex.go index d0d8836..0bc4e19 100644 --- a/addMutex.go +++ b/addMutex.go @@ -14,7 +14,7 @@ import ( ) func (pf *File) syncLock(w io.Writer) { - var LOCK string = pf.Bases.Lockname + var LOCK string = pf.Base.Lockname // if the Marshall code changes, this will have to change fmt.Fprintln(w, "// a simple global lock") fmt.Fprintln(w, "") @@ -95,19 +95,20 @@ func (pf *File) structMatch(line string) bool { start = "type " + msg.Name + " struct {" if strings.HasPrefix(line, start) { msg.MutexFound = true + msg.Lockname = "x.Lock" return true } // ONLY PASS THIS IF YOU DO NOT WANT TO USE MARSHAL() - if argv.Marshal { - return false - } - msg = pf.Base start = "type " + msg.Name + " struct {" if strings.HasPrefix(line, start) { msg.MutexFound = true + if argv.Marshal { + // msg.Lockname = "fruitMu.Lock" + return false + } return true } @@ -115,6 +116,10 @@ func (pf *File) structMatch(line string) bool { start = "type " + msg.Name + " struct {" if strings.HasPrefix(line, start) { msg.MutexFound = true + if argv.Marshal { + // msg.Lockname = "fruitMu.Lock" + return false + } return true } } diff --git a/example/Makefile b/example/Makefile index f704534..66edeaf 100644 --- a/example/Makefile +++ b/example/Makefile @@ -1,7 +1,7 @@ VERSION = $(shell git describe --tags) BUILDTIME = $(shell date +%Y.%m.%d_%H%M) -test: goimports build +all: clean simpleMutexProtoc goimports build ./example modproto: clean withMutex goimports vet build @@ -46,4 +46,4 @@ goimports: clean: -rm -f go.* -rm -f *.pb.go - -rm -f testfiles + -rm -f example basket.pb diff --git a/example/main.go b/example/main.go index a248fed..078dbce 100644 --- a/example/main.go +++ b/example/main.go @@ -19,20 +19,18 @@ var sortmap map[string]string var marshalKeys []string var uniqueKeys []string -var pb *Fruits +var counter int = rand.Intn(100) func main() { - pb = NewFruits() + var pb *Fruits + // pb = NewFruits() + pb = new(Fruits) // attempt to load basket.pb if err := pb.loadBasket(); err != nil { log.Info("load basket failed. running this for the first time?") - fruit := &Fruit{ - Brand: "mom", - City: "New NewYork", - UPC: "2000", - } - testAppend(fruit) - appendByUPC() + a := pb.getNewFruit() + pb.Fruits = append(pb.Fruits, a) + pb.printTable() } if err := pb.saveBasket(); err != nil { badExit(err) @@ -40,7 +38,6 @@ func main() { if pb == nil { badExit(fmt.Errorf("pb == nil This should not have happened")) } - pb.printTable() pb.addThings() pb.printTable() pb.saveBasket() @@ -52,6 +49,17 @@ func badExit(err error) { os.Exit(-1) } +func (pb *Fruits) getNewFruit() *Fruit { + counter += rand.Intn(100) + upc := fmt.Sprintf("%d", counter) + fut := &Fruit{ + Brand: "mom", + City: "New NewYork", + UPC: upc, + } + return fut +} + /* x := new(Fruit) x = &Fruit{ @@ -130,36 +138,6 @@ func (pb *Fruits) addThings() { } } -func testAppend(fruit *Fruit) { - if pb.AppendUnique(fruit) { - log.Info("AppendUnique() test1 ok", fruit.Brand, fruit.City) - } else { - badExit(fmt.Errorf("AppendUnique test1 failed %s %s %d\n", fruit.Brand, fruit.City, pb.Len())) - } - if pb.AppendUnique(fruit) { - badExit(fmt.Errorf("AppendUnique() test2 worked but should not have %s %s", fruit.Brand, fruit.City)) - } else { - log.Info("AppendUnique() test2 failed ok", fruit.Brand, fruit.City) - } -} - -func appendByUPC() { - fruit := new(Fruit) - fruit.UPC = "blah331" - fruit.City = "fry" - fruit.City = "paris" - if pb.AppendUniqueByUPC(fruit) { - log.Info("AppendUnique() test1 ok", fruit.Brand, fruit.City) - } else { - badExit(fmt.Errorf("AppendUniqueByUPC test1 failed %s %s %d\n", fruit.Brand, fruit.City, pb.Len())) - } - if pb.AppendUniqueByUPC(fruit) { - badExit(fmt.Errorf("AppendUniqueByUPC() test2 worked but should not have %s %s", fruit.Brand, fruit.City)) - } else { - log.Info("AppendUnique() test2 failed ok", fruit.Brand, fruit.City) - } -} - func (pb *Fruits) saveBasket() error { data, err := pb.Marshal() if err != nil { diff --git a/small/Makefile b/small/Makefile new file mode 100644 index 0000000..95a9c0c --- /dev/null +++ b/small/Makefile @@ -0,0 +1,49 @@ +VERSION = $(shell git describe --tags) +BUILDTIME = $(shell date +%Y.%m.%d_%H%M) + +all: clean simpleMutexProtoc goimports build + ./small + +modproto: clean withMutex goimports vet build + ./small + +rawproto: clean withoutMutex goimports vet build + ./small + +vet: + @GO111MODULE=off go vet + +build: + GO111MODULE=off go build -v + +simpleMutexProtoc: + ../autogenpb --proto fruit.proto --package main + +# why does this fail to compile? I'm not sure. maybe someone smart can figure it out +# basically, it just trys to return the deleted record but says something +# about the RWmutex lock being copied and GO fails to compile +# I'm don't grok what is going on. This autogenerated code should +# provide as simple as one could hope for automated way to try to debug it though! +simpleMutexProtocWithDeleteCopy: + ../autogenpb --proto fruit.proto --package main --delete + +simpleMutexGlobal: + ../autogenpb --proto fruit.proto --package main --mutex=false + +withMutex: + ../autogenpb --proto fruit.proto --package main + ../autogenpb --proto file.proto --package main + ../autogenpb --proto patchset.proto --package main + +withoutMutex: + ../autogenpb --proto fruit.proto --package main --mutex=false + ../autogenpb --proto file.proto --package main --mutex=false + ../autogenpb --proto patchset.proto --package main --mutex=false + +goimports: + goimports -w *.go + +clean: + -rm -f go.* + -rm -f *.pb.go + -rm -f small basket.pb diff --git a/small/fruit.New.go b/small/fruit.New.go new file mode 100644 index 0000000..0be9b07 --- /dev/null +++ b/small/fruit.New.go @@ -0,0 +1,9 @@ +package main + +func NewFruits() *Fruits { + x := new(Fruits) + x.Uuid = "test" + x.Version = "v0.0.2" + // x.Fruits = + return x +} diff --git a/small/fruit.proto b/small/fruit.proto new file mode 100644 index 0000000..341617d --- /dev/null +++ b/small/fruit.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package fruit; + +import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp + +// "Fruit" must exist. you can put anything in it +message Fruit { + string brand = 1; + string UPC = 2; + string city = 3; +} + +// "Fruits" MUST EXIST and start exactly this way +// It must be "Fruit" + 's' and must match the name of this file: "fruit.proto" +message Fruits { // `autogenpb:marshal` + string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079` + string version = 2; // `autogenpb:version:v0.0.1` + repeated Fruit Fruits = 3; // THIS MUST BE "Fruit" and then "Fruit" + "s" +} diff --git a/small/main.go b/small/main.go new file mode 100644 index 0000000..f8e5d60 --- /dev/null +++ b/small/main.go @@ -0,0 +1,60 @@ +//go:build go1.20 +// +build go1.20 + +package main + +import ( + "os" + + "go.wit.com/log" +) + +// sent via -ldflags +var VERSION string +var BUILDTIME string + +var sortmap map[string]string +var marshalKeys []string +var uniqueKeys []string + +func main() { + var pb *Fruits + pb = new(Fruits) + // attempt to load basket.pb + fruit := &Fruit{ + Brand: "mom", + City: "New NewYork", + UPC: "2000", + } + pb.Fruits = append(pb.Fruits, fruit) + + a := &Fruit{ + Brand: "fry", + City: "the moon", + UPC: "2001", + } + pb.Fruits = append(pb.Fruits, a) + + pb.saveBasket() +} + +func (pb *Fruits) saveBasket() error { + data, err := pb.Marshal() + if err != nil { + return err + } + + w, err := os.OpenFile("basket.pb", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + w.Write(data) + w.Close() + log.Info("saved basket.pb ok") + return nil +} + +func badExit(err error) { + log.Info("autogenpb error:", err) + os.Exit(-1) +} diff --git a/sort.go b/sort.go index e7f4946..a63b067 100644 --- a/sort.go +++ b/sort.go @@ -21,14 +21,12 @@ func (pb *Files) makeNewSortfile(pf *File) error { header(wSort, pf) header(wFind, pf) - if !argv.Mutex { - pf.syncLock(wSort) - } + pf.syncLock(wSort) - if argv.Mutex { - // use the mutex lock from the modified protoc.pb.go file - pf.Bases.Lockname = "all.Lock" - } + // if argv.Mutex { + // // use the mutex lock from the modified protoc.pb.go file + // pf.Bases.Lockname = "all.Lock" + // } pf.Base.iterTop(wSort) pf.Base.iterNext(wSort) diff --git a/sortFunc.go b/sortFunc.go index e12db51..361462b 100644 --- a/sortFunc.go +++ b/sortFunc.go @@ -57,18 +57,18 @@ func (pf *File) selectAllFunc(w io.Writer) { var BASE string = pf.Base.Name var LOCK string = pf.Bases.Lockname - fmt.Fprintln(w, "func (all *"+BASES+") All() *"+BASE+"Iterator {") - fmt.Fprintln(w, " "+BASE+"Pointers := all.selectAll"+BASE+"()") + fmt.Fprintln(w, "func (x *"+BASES+") All() *"+BASE+"Iterator {") + fmt.Fprintln(w, " "+BASE+"Pointers := x.selectAll"+BASE+"()") fmt.Fprintln(w, "") fmt.Fprintln(w, " iterator := New"+BASE+"Iterator("+BASE+"Pointers)") fmt.Fprintln(w, " return iterator") fmt.Fprintln(w, "}") fmt.Fprintln(w, "") - fmt.Fprintln(w, "func (all *"+BASES+") Len() int {") + fmt.Fprintln(w, "func (x *"+BASES+") Len() int {") fmt.Fprintln(w, " "+LOCK+".RLock()") fmt.Fprintln(w, " defer "+LOCK+".RUnlock()") fmt.Fprintln(w, "") - fmt.Fprintln(w, " return len(all."+BASES+")") + fmt.Fprintln(w, " return len(x."+BASES+")") fmt.Fprintln(w, "}") fmt.Fprintln(w, "") } @@ -78,8 +78,8 @@ func (pf *File) sortByFunc(w io.Writer) { var BASE string = pf.Base.Name for _, SORT := range pf.Base.Sort { - fmt.Fprintln(w, "func (all *"+BASES+") SortBy"+SORT+"() *"+BASE+"Iterator {") - fmt.Fprintln(w, " things := all.selectAll"+BASE+"()") + fmt.Fprintln(w, "func (x *"+BASES+") SortBy"+SORT+"() *"+BASE+"Iterator {") + fmt.Fprintln(w, " things := x.selectAll"+BASE+"()") fmt.Fprintln(w, "") fmt.Fprintln(w, " sort.Sort("+BASE+""+SORT+"(things))") fmt.Fprintln(w, "") @@ -103,14 +103,14 @@ func (pf *File) iterSelect(w io.Writer) { var LOCK string = pf.Bases.Lockname fmt.Fprintln(w, "// safely returns a slice of pointers to the "+BASE+" protobufs") - fmt.Fprintln(w, "func (all *"+BASES+") selectAll"+BASE+"() []*"+BASE+" {") + fmt.Fprintln(w, "func (x *"+BASES+") selectAll"+BASE+"() []*"+BASE+" {") fmt.Fprintln(w, " "+LOCK+".RLock()") fmt.Fprintln(w, " defer "+LOCK+".RUnlock()") fmt.Fprintln(w, "") fmt.Fprintln(w, " // Create a new slice to hold pointers to each "+BASE+"") fmt.Fprintln(w, " var tmp []*"+BASE+"") - fmt.Fprintln(w, " tmp = make([]*"+BASE+", len(all."+BASES+"))") - fmt.Fprintln(w, " for i, p := range all."+BASES+" {") + fmt.Fprintln(w, " tmp = make([]*"+BASE+", len(x."+BASES+"))") + fmt.Fprintln(w, " for i, p := range x."+BASES+" {") fmt.Fprintln(w, " tmp[i] = p // Copy pointers for safe iteration") fmt.Fprintln(w, " }") fmt.Fprintln(w, "") diff --git a/sortNew.go b/sortNew.go index 1de2e82..72370ba 100644 --- a/sortNew.go +++ b/sortNew.go @@ -8,11 +8,11 @@ import ( ) func (msg *MsgName) getLockname(s string) string { - if argv.Mutex { - // use the mutex lock from the modified protoc.pb.go file - return s + ".Lock" - // return s // causes Marshal() to panic? always use the variable name 'Lock'? - } + // if argv.Mutex { + // // use the mutex lock from the modified protoc.pb.go file + // return s + ".Lock" + // // return s // causes Marshal() to panic? always use the variable name 'Lock'? + // } // a single global lock by struct name return msg.Lockname }