Skip to content

Commit 48824cb

Browse files
committed
hash the executable for standalone versioning
1 parent 3befd0b commit 48824cb

File tree

2 files changed

+30
-61
lines changed

2 files changed

+30
-61
lines changed

dbos/dbos.go

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ import (
66
"encoding/gob"
77
"encoding/hex"
88
"fmt"
9+
"io"
910
"log/slog"
1011
"net/url"
1112
"os"
12-
"reflect"
13-
"runtime"
14-
"sort"
1513
"time"
1614

1715
"github.com/robfig/cron/v3"
@@ -24,36 +22,6 @@ var (
2422
_DEFAULT_ADMIN_SERVER_PORT = 3001
2523
)
2624

27-
func computeApplicationVersion() string {
28-
if len(registry) == 0 {
29-
fmt.Println("DBOS: No registered workflows found, cannot compute application version")
30-
return ""
31-
}
32-
33-
// Collect all function names and sort them for consistent hashing
34-
var functionNames []string
35-
for fqn := range registry {
36-
functionNames = append(functionNames, fqn)
37-
}
38-
sort.Strings(functionNames)
39-
40-
hasher := sha256.New()
41-
42-
for _, fqn := range functionNames {
43-
workflowEntry := registry[fqn]
44-
45-
// Try to get function source location and other identifying info
46-
if pc := runtime.FuncForPC(reflect.ValueOf(workflowEntry.wrappedFunction).Pointer()); pc != nil {
47-
// Get the function's entry point - this reflects the actual compiled code
48-
entry := pc.Entry()
49-
fmt.Fprintf(hasher, "%x", entry)
50-
}
51-
}
52-
53-
return hex.EncodeToString(hasher.Sum(nil))
54-
55-
}
56-
5725
var workflowScheduler *cron.Cron // Global because accessed during workflow registration before the dbos singleton is initialized
5826

5927
var logger *slog.Logger // Global because accessed everywhere inside the library
@@ -278,3 +246,32 @@ func Shutdown() {
278246
}
279247
dbos = nil
280248
}
249+
250+
func GetBinaryHash() (string, error) {
251+
execPath, err := os.Executable()
252+
if err != nil {
253+
return "", err
254+
}
255+
256+
file, err := os.Open(execPath)
257+
if err != nil {
258+
return "", err
259+
}
260+
defer file.Close()
261+
262+
hasher := sha256.New()
263+
if _, err := io.Copy(hasher, file); err != nil {
264+
return "", err
265+
}
266+
267+
return hex.EncodeToString(hasher.Sum(nil)), nil
268+
}
269+
270+
func computeApplicationVersion() string {
271+
hash, err := GetBinaryHash()
272+
if err != nil {
273+
fmt.Printf("DBOS: Failed to compute binary hash: %v\n", err)
274+
return ""
275+
}
276+
return hash
277+
}

dbos/dbos_test.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package dbos
22

33
import (
4-
"context"
5-
"encoding/hex"
6-
"maps"
74
"testing"
85
)
96

@@ -60,28 +57,3 @@ func TestConfigValidationErrorTypes(t *testing.T) {
6057
}
6158
})
6259
}
63-
func TestAppVersion(t *testing.T) {
64-
if _, err := hex.DecodeString(_APP_VERSION); err != nil {
65-
t.Fatalf("APP_VERSION is not a valid hex string: %v", err)
66-
}
67-
68-
// Save the original registry content
69-
originalRegistry := make(map[string]workflowRegistryEntry)
70-
maps.Copy(originalRegistry, registry)
71-
72-
// Restore the registry after the test
73-
defer func() {
74-
registry = originalRegistry
75-
}()
76-
77-
// Replace the registry and verify the hash is different
78-
registry = make(map[string]workflowRegistryEntry)
79-
80-
WithWorkflow(func(ctx context.Context, input string) (string, error) {
81-
return "new-registry-workflow-" + input, nil
82-
})
83-
hash2 := computeApplicationVersion()
84-
if _APP_VERSION == hash2 {
85-
t.Fatalf("APP_VERSION hash did not change after replacing registry")
86-
}
87-
}

0 commit comments

Comments
 (0)