feat: add Golang and examples

This commit is contained in:
Bogdan Buduroiu 2025-03-30 22:59:32 +08:00
parent 4ed33ddb4e
commit 502b8cefc1
Signed by: bruvduroiu
GPG key ID: A8722B2334DE9499
5 changed files with 228 additions and 61 deletions

3
.gitmodules vendored
View file

@ -10,3 +10,6 @@
[submodule "vendor/tree-sitter-python"] [submodule "vendor/tree-sitter-python"]
path = vendor/tree-sitter-python path = vendor/tree-sitter-python
url = https://github.com/tree-sitter/tree-sitter-python url = https://github.com/tree-sitter/tree-sitter-python
[submodule "vendor/tree-sitter-go"]
path = vendor/tree-sitter-go
url = https://github.com/tree-sitter/tree-sitter-go

125
README.md
View file

@ -23,6 +23,9 @@ zig build
## Examples ## Examples
<details>
<summary>Python</summary>
```python ```python
from typing import Union from typing import Union
@ -52,6 +55,10 @@ func read_root() -> void;
func read_item() -> void; func read_item() -> void;
``` ```
</details>
<details>
<summary>Zig</summary>
```zig ```zig
const std = @import("std"); const std = @import("std");
@ -106,3 +113,121 @@ var p;
var normal; var normal;
var face; var face;
``` ```
</details>
<details>
<summary>Go</summary>
```go
package batch_sliding_window
import (
"fmt"
"go.temporal.io/sdk/temporal"
"go.temporal.io/sdk/workflow"
"time"
)
// ProcessBatchWorkflowInput input of the ProcessBatchWorkflow.
// A single input structure is preferred to multiple workflow arguments to simplify backward compatible API changes.
type ProcessBatchWorkflowInput struct {
PageSize int // Number of children started by a single sliding window workflow run
SlidingWindowSize int // Maximum number of children to run in parallel.
Partitions int // How many sliding windows to run in parallel.
}
// ProcessBatchWorkflow sample Partitions the data set into continuous ranges.
// A real application can choose any other way to divide the records into multiple collections.
func ProcessBatchWorkflow(ctx workflow.Context, input ProcessBatchWorkflowInput) (processed int, err error) {
ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
StartToCloseTimeout: 5 * time.Second,
})
var recordLoader *RecordLoader // RecordLoader activity reference
var recordCount int
err = workflow.ExecuteActivity(ctx, recordLoader.GetRecordCount).Get(ctx, &recordCount)
if err != nil {
return 0, err
}
if input.SlidingWindowSize < input.Partitions {
return 0, temporal.NewApplicationError(
"SlidingWindowSize cannot be less than number of partitions", "invalidInput")
}
partitions := divideIntoPartitions(recordCount, input.Partitions)
windowSizes := divideIntoPartitions(input.SlidingWindowSize, input.Partitions)
workflow.GetLogger(ctx).Info("ProcessBatchWorkflow",
"input", input,
"recordCount", recordCount,
"partitions", partitions,
"windowSizes", windowSizes)
var results []workflow.ChildWorkflowFuture
offset := 0
for i := 0; i < input.Partitions; i++ {
// Makes child id more user-friendly
childId := fmt.Sprintf("%s/%d", workflow.GetInfo(ctx).WorkflowExecution.ID, i)
childCtx := workflow.WithChildOptions(ctx, workflow.ChildWorkflowOptions{WorkflowID: childId})
// Define partition boundaries.
maximumPartitionOffset := offset + partitions[i]
if maximumPartitionOffset > recordCount {
maximumPartitionOffset = recordCount
}
input := SlidingWindowWorkflowInput{
PageSize: input.PageSize,
SlidingWindowSize: windowSizes[i],
Offset: offset, // inclusive
MaximumOffset: maximumPartitionOffset, // exclusive
}
child := workflow.ExecuteChildWorkflow(childCtx, SlidingWindowWorkflow, input)
results = append(results, child)
offset += partitions[i]
}
// Waits for all child workflows to complete
result := 0
for _, partitionResult := range results {
var r int
err := partitionResult.Get(ctx, &r) // blocks until the child completion
if err != nil {
return 0, err
}
result += r
}
return result, nil
}
func divideIntoPartitions(number int, n int) []int {
base := number / n
remainder := number % n
partitions := make([]int, n)
for i := 0; i < n; i++ {
partitions[i] = base
}
for i := 0; i < remainder; i++ {
partitions[i] += 1
}
return partitions
}
```
Result:
```
File: /Users/bogdanbuduroiu/development/temporalio/samples-go/batch-
sliding-window/batch_workflow.go
Language: go
class ProcessBatchWorkflowInput {
};
var PageSize;
var SlidingWindowSize;
var Partitions;
func ProcessBatchWorkflow() -> void;
func divideIntoPartitions() -> void;
```
</details>

View file

@ -80,7 +80,7 @@ pub fn build(b: *std.Build) void {
exe.linkLibrary(tree_sitter.artifact("zig-tree-sitter")); exe.linkLibrary(tree_sitter.artifact("zig-tree-sitter"));
// Build language level packages // Build language level packages
const supported_langs: [3][]const u8 = .{ "c", "python", "zig" }; const supported_langs: [4][]const u8 = .{ "c", "python", "zig", "go" };
const prefix = "tree-sitter-"; const prefix = "tree-sitter-";
inline for (supported_langs) |lang| { inline for (supported_langs) |lang| {
const name = comptime blk: { const name = comptime blk: {

View file

@ -5,11 +5,13 @@ const Allocator = std.mem.Allocator;
extern fn tree_sitter_zig() callconv(.C) *ts.Language; extern fn tree_sitter_zig() callconv(.C) *ts.Language;
extern fn tree_sitter_c() callconv(.C) *ts.Language; extern fn tree_sitter_c() callconv(.C) *ts.Language;
extern fn tree_sitter_python() callconv(.C) *ts.Language; extern fn tree_sitter_python() callconv(.C) *ts.Language;
extern fn tree_sitter_go() callconv(.C) *ts.Language;
pub const LanguageType = enum { pub const LanguageType = enum {
python, python,
zig, zig,
c, c,
go,
unknown, unknown,
pub fn fromExtension(ext: []const u8) LanguageType { pub fn fromExtension(ext: []const u8) LanguageType {
@ -19,6 +21,8 @@ pub const LanguageType = enum {
return .zig; return .zig;
} else if (std.mem.eql(u8, ext, ".c") or std.mem.eql(u8, ext, ".h")) { } else if (std.mem.eql(u8, ext, ".c") or std.mem.eql(u8, ext, ".h")) {
return .c; return .c;
} else if (std.mem.eql(u8, ext, ".go")) {
return .go;
} else { } else {
return .unknown; return .unknown;
} }
@ -29,6 +33,7 @@ pub const LanguageType = enum {
.python => "python", .python => "python",
.zig => "zig", .zig => "zig",
.c => "c", .c => "c",
.go => "go",
.unknown => "unknown", .unknown => "unknown",
}; };
} }
@ -38,6 +43,7 @@ pub const LanguageType = enum {
.python => tree_sitter_python(), .python => tree_sitter_python(),
.zig => tree_sitter_zig(), .zig => tree_sitter_zig(),
.c => tree_sitter_c(), .c => tree_sitter_c(),
.go => tree_sitter_go(),
.unknown => null, .unknown => null,
}; };
} }
@ -132,6 +138,38 @@ pub const LanguageType = enum {
\\ (storage_class_specifier) @extern \\ (storage_class_specifier) @extern
\\) @variable \\) @variable
, ,
.go =>
\\;; Capture top-level functions and struct definitions
\\(source_file
\\ (var_declaration
\\ (var_spec) @variable
\\ )
\\)
\\(source_file
\\ (const_declaration
\\ (const_spec) @variable
\\ )
\\)
\\(source_file
\\ (function_declaration) @function
\\)
\\(source_file
\\ (type_declaration
\\ (type_spec (struct_type)) @class
\\ )
\\)
\\(source_file
\\ (type_declaration
\\ (type_spec
\\ (struct_type
\\ (field_declaration_list
\\ (field_declaration) @class_variable)))
\\ )
\\)
\\(source_file
\\ (method_declaration) @method
\\)
,
.unknown => null, .unknown => null,
}; };
} }

1
vendor/tree-sitter-go vendored Submodule

@ -0,0 +1 @@
Subproject commit 5e73f476efafe5c768eda19bbe877f188ded6144