feat: add Golang and examples
This commit is contained in:
parent
4ed33ddb4e
commit
502b8cefc1
5 changed files with 228 additions and 61 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -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
125
README.md
|
@ -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>
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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
1
vendor/tree-sitter-go
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 5e73f476efafe5c768eda19bbe877f188ded6144
|
Loading…
Add table
Reference in a new issue