This is an automated email from the ASF dual-hosted git repository.
xuetaoli pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 7acdd578e Expose api of router (#3066)
7acdd578e is described below
commit 7acdd578e2cd54f67e6e203821691762ea826508
Author: Zhang Qi <[email protected]>
AuthorDate: Tue Dec 2 10:28:26 2025 +0800
Expose api of router (#3066)
* fix(test): relax EOF assertion for concurrent triple stream tests (#3062)
---------
Co-authored-by: zbchi <[email protected]>
Co-authored-by: Qi.Zhang <[email protected]>
Co-authored-by: Xuetao Li <[email protected]>
---
cluster/router/options.go | 97 +++++++++++++++++++
compat.go | 104 +++++++++++++++++++++
global/router_config.go | 24 ++++-
options.go | 26 +++++-
protocol/triple/triple_protocol/triple_ext_test.go | 20 +++-
.../generator/sample/hessian/constant.go | 8 +-
.../generator/sample/hessian/generator.go | 56 ++++++-----
7 files changed, 300 insertions(+), 35 deletions(-)
diff --git a/cluster/router/options.go b/cluster/router/options.go
new file mode 100644
index 000000000..63a47bb30
--- /dev/null
+++ b/cluster/router/options.go
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package router
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/global"
+)
+
+type Options struct {
+ Router *global.RouterConfig
+}
+
+func defaultOptions() *Options {
+ return &Options{
+ Router: global.DefaultRouterConfig(),
+ }
+}
+
+func NewOptions(opts ...Option) *Options {
+ defOpts := defaultOptions()
+ for _, opt := range opts {
+ opt(defOpts)
+ }
+ return defOpts
+}
+
+type Option func(*Options)
+
+func WithScope(scope string) Option {
+ return func(opts *Options) {
+ opts.Router.Scope = scope
+ }
+}
+
+func WithKey(key string) Option {
+ return func(opts *Options) {
+ opts.Router.Key = key
+ }
+}
+
+func WithForce(force bool) Option {
+ return func(opts *Options) {
+ opts.Router.Force = &force
+ }
+}
+
+func WithRuntime(runtime bool) Option {
+ return func(opts *Options) {
+ opts.Router.Force = &runtime
+ }
+}
+
+func WithEnabled(enabled bool) Option {
+ return func(opts *Options) {
+ opts.Router.Force = &enabled
+ }
+}
+
+func WithValid(valid bool) Option {
+ return func(opts *Options) {
+ opts.Router.Valid = &valid
+ }
+}
+
+func WithPriority(priority int) Option {
+ return func(opts *Options) {
+ opts.Router.Priority = priority
+ }
+}
+
+func WithConditions(conditions []string) Option {
+ return func(opts *Options) {
+ opts.Router.Conditions = conditions
+ }
+}
+
+func WithTags(tags []global.Tag) Option {
+ return func(opts *Options) {
+ opts.Router.Tags = tags
+ }
+
+}
diff --git a/compat.go b/compat.go
index e61261e9c..7844ba5b1 100644
--- a/compat.go
+++ b/compat.go
@@ -22,6 +22,7 @@ import (
)
import (
+ "dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/config"
"dubbo.apache.org/dubbo-go/v3/global"
)
@@ -40,6 +41,10 @@ func compatRootConfig(c *InstanceOptions) *config.RootConfig
{
regCompat[k] = compatRegistryConfig(v)
}
+ routeCompat := make([]*config.RouterConfig, 0)
+ for _, v := range c.Router {
+ routeCompat = append(routeCompat, compatRouterConfig(v))
+ }
return &config.RootConfig{
Application: compatApplicationConfig(c.Application),
Protocols: proCompat,
@@ -52,6 +57,7 @@ func compatRootConfig(c *InstanceOptions) *config.RootConfig {
Otel: compatOtelConfig(c.Otel),
Logger: compatLoggerConfig(c.Logger),
Shutdown: compatShutdownConfig(c.Shutdown),
+ Router: routeCompat,
EventDispatcherType: c.EventDispatcherType,
CacheFile: c.CacheFile,
Custom: compatCustomConfig(c.Custom),
@@ -437,6 +443,54 @@ func compatShutdownConfig(c *global.ShutdownConfig)
*config.ShutdownConfig {
return cfg
}
+func compatRouterConfig(c *global.RouterConfig) *config.RouterConfig {
+ if c == nil {
+ return nil
+ }
+ return &config.RouterConfig{
+ Scope: c.Scope,
+ Key: c.Key,
+ Force: c.Force,
+ Runtime: c.Runtime,
+ Enabled: c.Enabled,
+ Valid: c.Valid,
+ Priority: c.Priority,
+ Conditions: c.Conditions,
+ Tags: compatTags(c.Tags),
+ ScriptType: c.ScriptType,
+ Script: c.Script,
+ }
+
+}
+
+func compatTags(c []global.Tag) []config.Tag {
+ if c == nil {
+ return nil
+ }
+ // deep copy
+ tags := make([]config.Tag, len(c))
+
+ for i := range c {
+ tags[i].Name = c[i].Name
+ if c[i].Match != nil {
+ tags[i].Match = make([]*common.ParamMatch,
len(c[i].Match))
+ for j := range c[i].Match {
+ if c[i].Match[j] != nil {
+ pm := *c[i].Match[j]
+ tags[i].Match[j] = &pm
+ }
+ }
+ }
+
+ if c[i].Addresses != nil {
+ tags[i].Addresses = make([]string, len(c[i].Addresses))
+ copy(tags[i].Addresses, c[i].Addresses)
+ }
+ }
+
+ return tags
+}
+
func compatCustomConfig(c *global.CustomConfig) *config.CustomConfig {
if c == nil {
return nil
@@ -514,6 +568,11 @@ func compatInstanceOptions(cr *config.RootConfig, rc
*InstanceOptions) {
regCompat[k] = compatGlobalRegistryConfig(v)
}
+ rouCompat := make([]*global.RouterConfig, 0)
+ for _, v := range cr.Router {
+ rouCompat = append(rouCompat, compatGlobalRouterConfig(v))
+ }
+
rc.Application = compatGlobalApplicationConfig(cr.Application)
rc.Protocols = proCompat
rc.Registries = regCompat
@@ -525,6 +584,7 @@ func compatInstanceOptions(cr *config.RootConfig, rc
*InstanceOptions) {
rc.Otel = compatGlobalOtelConfig(cr.Otel)
rc.Logger = compatGlobalLoggerConfig(cr.Logger)
rc.Shutdown = compatGlobalShutdownConfig(cr.Shutdown)
+ rc.Router = rouCompat
rc.EventDispatcherType = cr.EventDispatcherType
rc.CacheFile = cr.CacheFile
rc.Custom = compatGlobalCustomConfig(cr.Custom)
@@ -964,6 +1024,50 @@ func compatGlobalShutdownConfig(c *config.ShutdownConfig)
*global.ShutdownConfig
return cfg
}
+func compatGlobalRouterConfig(c *config.RouterConfig) *global.RouterConfig {
+ if c == nil {
+ return nil
+ }
+ return &global.RouterConfig{
+ Scope: c.Scope,
+ Key: c.Key,
+ Force: c.Force,
+ Runtime: c.Runtime,
+ Enabled: c.Enabled,
+ Valid: c.Valid,
+ Priority: c.Priority,
+ Conditions: c.Conditions,
+ Tags: compatGlobalTag(c.Tags),
+ ScriptType: c.ScriptType,
+ Script: c.Script,
+ }
+}
+
+func compatGlobalTag(c []config.Tag) []global.Tag {
+ if c == nil {
+ return nil
+ }
+ // deepcopy
+ tags := make([]global.Tag, len(c))
+ for i := range c {
+ tags[i].Name = c[i].Name
+ if c[i].Match != nil {
+ tags[i].Match = make([]*common.ParamMatch,
len(c[i].Match))
+ for j := range c[i].Match {
+ if c[i].Match[j] != nil {
+ pm := *c[i].Match[j]
+ tags[i].Match[j] = &pm
+ }
+ }
+ }
+ if c[i].Addresses != nil {
+ tags[i].Addresses = make([]string, len(c[i].Addresses))
+ copy(tags[i].Addresses, c[i].Addresses)
+ }
+ }
+ return tags
+}
+
func compatGlobalCustomConfig(c *config.CustomConfig) *global.CustomConfig {
if c == nil {
return nil
diff --git a/global/router_config.go b/global/router_config.go
index 9b161b5eb..948cb5631 100644
--- a/global/router_config.go
+++ b/global/router_config.go
@@ -41,6 +41,13 @@ type Tag struct {
Addresses []string `yaml:"addresses"
json:"addresses,omitempty" property:"addresses"`
}
+func DefaultRouterConfig() *RouterConfig {
+ return &RouterConfig{
+ Conditions: make([]string, 0),
+ Tags: make([]Tag, 0),
+ }
+}
+
type ConditionRule struct {
From ConditionRuleFrom `yaml:"from" json:"from,omitempty"
property:"from"`
To []ConditionRuleTo `yaml:"to" json:"to,omitempty" property:"to"`
@@ -116,7 +123,22 @@ func (c *RouterConfig) Clone() *RouterConfig {
copy(newConditions, c.Conditions)
newTags := make([]Tag, len(c.Tags))
- copy(newTags, c.Tags)
+ for i := range c.Tags {
+ newTags[i] = c.Tags[i]
+ if c.Tags[i].Match != nil {
+ newTags[i].Match = make([]*common.ParamMatch,
len(c.Tags[i].Match))
+ for j := range c.Tags[i].Match {
+ if c.Tags[i].Match[j] != nil {
+ pm := *c.Tags[i].Match[j] // 深拷贝
ParamMatch(包含 Value:StringMatch)
+ newTags[i].Match[j] = &pm
+ }
+ }
+ }
+ if c.Tags[i].Addresses != nil {
+ newTags[i].Addresses = make([]string,
len(c.Tags[i].Addresses))
+ copy(newTags[i].Addresses, c.Tags[i].Addresses)
+ }
+ }
return &RouterConfig{
Scope: c.Scope,
diff --git a/options.go b/options.go
index 46df750b6..4f303775c 100644
--- a/options.go
+++ b/options.go
@@ -27,6 +27,7 @@ import (
)
import (
+ "dubbo.apache.org/dubbo-go/v3/cluster/router"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/config"
"dubbo.apache.org/dubbo-go/v3/config_center"
@@ -54,7 +55,7 @@ type InstanceOptions struct {
Logger *global.LoggerConfig `yaml:"logger"
json:"logger,omitempty" property:"logger"`
Shutdown *global.ShutdownConfig `yaml:"shutdown"
json:"shutdown,omitempty" property:"shutdown"`
// todo(DMwangnima): router feature would be supported in the future
- //Router []*RouterConfig `yaml:"router"
json:"router,omitempty" property:"router"`
+ Router []*global.RouterConfig `yaml:"router"
json:"router,omitempty" property:"router"`
EventDispatcherType string `default:"direct"
yaml:"event-dispatcher-type" json:"event-dispatcher-type,omitempty"`
CacheFile string `yaml:"cache_file"
json:"cache_file,omitempty" property:"cache_file"`
Custom *global.CustomConfig `yaml:"custom"
json:"custom,omitempty" property:"custom"`
@@ -75,6 +76,7 @@ func defaultInstanceOptions() *InstanceOptions {
Otel: global.DefaultOtelConfig(),
Logger: global.DefaultLoggerConfig(),
Shutdown: global.DefaultShutdownConfig(),
+ Router: make([]*global.RouterConfig, 0),
Custom: global.DefaultCustomConfig(),
Profiles: global.DefaultProfilesConfig(),
TLSConfig: global.DefaultTLSConfig(),
@@ -292,6 +294,17 @@ func (rc *InstanceOptions) CloneShutdown()
*global.ShutdownConfig {
return rc.Shutdown.Clone()
}
+func (rc *InstanceOptions) CloneRouter() []*global.RouterConfig {
+ if rc.Router == nil {
+ return nil
+ }
+ routers := make([]*global.RouterConfig, 0, len(rc.Router))
+ for _, r := range rc.Router {
+ routers = append(routers, r.Clone())
+ }
+ return routers
+}
+
func (rc *InstanceOptions) CloneCustom() *global.CustomConfig {
if rc.Custom == nil {
return nil
@@ -471,6 +484,17 @@ func WithShutdown(opts ...graceful_shutdown.Option)
InstanceOption {
}
}
+func WithRouter(opts ...router.Option) InstanceOption {
+ sdOpts := router.NewOptions(opts...)
+
+ return func(insOpts *InstanceOptions) {
+ if insOpts.Router == nil {
+ insOpts.Router = make([]*global.RouterConfig, 0)
+ }
+ insOpts.Router = append(insOpts.Router, sdOpts.Router)
+ }
+}
+
// todo(DMwangnima): enumerate specific EventDispatcherType
//func WithEventDispatcherType(typ string) InstanceOption {
// return func(cfg *InstanceOptions) {
diff --git a/protocol/triple/triple_protocol/triple_ext_test.go
b/protocol/triple/triple_protocol/triple_ext_test.go
index 40a54c2d7..6a08d0da6 100644
--- a/protocol/triple/triple_protocol/triple_ext_test.go
+++ b/protocol/triple/triple_protocol/triple_ext_test.go
@@ -1486,7 +1486,10 @@ func TestBidiStreamServerSendsFirstMessage(t *testing.T)
{
assert.Nil(t, stream.CloseRequest())
assert.Nil(t, stream.CloseResponse())
})
- assert.Nil(t, stream.Send(nil))
+ // tolerate EOF when server closes stream concurrently
+ if err = stream.Send(nil); err != nil {
+ assert.ErrorIs(t, err, io.EOF)
+ }
select {
case <-time.After(time.Second):
t.Error("timed out to get request headers")
@@ -1523,7 +1526,10 @@ func TestStreamForServer(t *testing.T) {
t.Cleanup(server.Close)
stream, err := client.CumSum(context.Background())
assert.Nil(t, err)
- assert.Nil(t, stream.Send(nil))
+ // tolerate EOF when server closes stream concurrently
+ if err = stream.Send(nil); err != nil {
+ assert.ErrorIs(t, err, io.EOF)
+ }
err = stream.Receive(&pingv1.CumSumResponse{})
assert.NotNil(t, err)
assert.Equal(t, triple.CodeOf(err), triple.CodeInternal)
@@ -1539,7 +1545,10 @@ func TestStreamForServer(t *testing.T) {
t.Cleanup(server.Close)
stream, err := client.CumSum(context.Background())
assert.Nil(t, err)
- assert.Nil(t, stream.Send(nil))
+ // tolerate EOF when server closes stream concurrently
+ if err = stream.Send(nil); err != nil {
+ assert.ErrorIs(t, err, io.EOF)
+ }
err = stream.Receive(&pingv1.CumSumResponse{})
assert.NotNil(t, err)
assert.Equal(t, triple.CodeOf(err), triple.CodeUnknown)
@@ -1558,7 +1567,10 @@ func TestStreamForServer(t *testing.T) {
t.Cleanup(server.Close)
stream, err := client.CumSum(context.Background())
assert.Nil(t, err)
- assert.Nil(t, stream.Send(nil))
+ // tolerate EOF when server closes stream concurrently
+ if err = stream.Send(nil); err != nil {
+ assert.ErrorIs(t, err, io.EOF)
+ }
assert.Nil(t, stream.CloseRequest())
})
t.Run("server-stream", func(t *testing.T) {
diff --git a/tools/dubbogo-cli/generator/sample/hessian/constant.go
b/tools/dubbogo-cli/generator/sample/hessian/constant.go
index 2b7cb4d8c..8c0b7b04c 100644
--- a/tools/dubbogo-cli/generator/sample/hessian/constant.go
+++ b/tools/dubbogo-cli/generator/sample/hessian/constant.go
@@ -26,13 +26,13 @@ const (
const (
PackageRegexp = `^package\s[a-zA-Z_][0-9a-zA-Z_]*$`
- LineCommentRegexp = `\/\/`
- MutLineCommentStartRegexp = `\/\*`
- MutLineCommentEndRegexp = `\*\/`
+ LineCommentRegexp = `//`
+ MutLineCommentStartRegexp = `/\*`
+ MutLineCommentEndRegexp = `\*/`
InitFunctionRegexp = `^func\sinit\(\)\s\{$`
- HessianImportRegexp = `"github.com/apache/dubbo-go-hessian2"`
+ HessianImportRegexp = `"github\.com/apache/dubbo\-go\-hessian2"`
HessianPOJORegexp =
`\*[0-9a-zA-Z_]+\)\sJavaClassName\(\)\sstring\s\{$`
HessianPOJONameRegexp = `\*[0-9a-zA-Z_]+\)`
diff --git a/tools/dubbogo-cli/generator/sample/hessian/generator.go
b/tools/dubbogo-cli/generator/sample/hessian/generator.go
index 7b0a66c3e..90482f0e7 100644
--- a/tools/dubbogo-cli/generator/sample/hessian/generator.go
+++ b/tools/dubbogo-cli/generator/sample/hessian/generator.go
@@ -79,7 +79,7 @@ func (g Generator) Execute() {
showLog(infoLog, "=== Generate completed [%s] ===", f)
}
-// scanFile 扫描文件内容
+// scanFile scans the file content
// nolint
func scanFile(filePath string) (file *fileInfo, err error) {
var f *os.File
@@ -99,6 +99,13 @@ func scanFile(filePath string) (file *fileInfo, err error) {
stack := make([][]byte, 0)
var line []byte
var lineSize int
+ var (
+ packageRegexp = regexp.MustCompile(PackageRegexp)
+ initFunctionRegexp = regexp.MustCompile(InitFunctionRegexp)
+ hessianImportRegexp = regexp.MustCompile(HessianImportRegexp)
+ lineCommentRegexp = regexp.MustCompile(LineCommentRegexp)
+ hessianPOJORegexp = regexp.MustCompile(HessianPOJORegexp)
+ )
for {
line, _, err = buf.ReadLine()
if err == io.EOF {
@@ -110,37 +117,36 @@ func scanFile(filePath string) (file *fileInfo, err
error) {
lineSize = len(line)
if file.hasInitFunc && lineSize > 0 && line[0] == funcEnd {
- file.initFuncEndIndex = bufferSize + 1 // 检测初始化函数结束位
+ file.initFuncEndIndex = bufferSize + 1 // Detect the
end position of the init function
}
buffer = append(buffer, line...)
buffer = append(buffer, newLine)
- if passed, _ := regexp.Match(PackageRegexp, line); passed { //
检测package位置
- file.packageStartIndex = bufferSize //
检测初始化函数初始位
- file.packageEndIndex = bufferSize + lineSize + 1 //
检测初始化函数初始位
+ if packageRegexp.Match(line) { // Detect package position
+ file.packageStartIndex = bufferSize //
Record start position of package
+ file.packageEndIndex = bufferSize + lineSize + 1 //
Record end position of package
continue
}
- if passed, _ := regexp.Match(InitFunctionRegexp, line); passed
{ // 检测初始化函数
+ if initFunctionRegexp.Match(line) { // Detect init function
file.hasInitFunc = true
- file.initFuncStartIndex = bufferSize
// 检测初始化函数初始位
- file.initFuncStatementStartIndex = bufferSize +
lineSize // 初始化函数方法体初始位
+ file.initFuncStartIndex = bufferSize
// Record start position of init function
+ file.initFuncStatementStartIndex = bufferSize +
lineSize // Record start position of init function body
continue
}
if !file.hasHessianImport {
- r, _ := regexp.Compile(HessianImportRegexp)
- rIndexList := r.FindIndex(line)
- if len(rIndexList) > 0 { // 检测是否已导入hessian2包
+ rIndexList := hessianImportRegexp.FindIndex(line)
+ if len(rIndexList) > 0 { // Detect whether hessian2
package has been imported
checkStatement := line[:rIndexList[0]]
- passed, _ := regexp.Match(LineCommentRegexp,
checkStatement) // 是否被行注释
+ passed :=
lineCommentRegexp.Match(checkStatement) // Check if it's commented out
file.hasHessianImport = !passed
continue
}
}
- if passed, _ := regexp.Match(HessianPOJORegexp, line); !passed
{ // 校验是否为Hessian.POJO实现类
+ if !hessianPOJORegexp.Match(line) { // Check whether it's a
Hessian.POJO implementation class
continue
}
structName := getStructName(line)
@@ -153,7 +159,7 @@ func scanFile(filePath string) (file *fileInfo, err error) {
return
}
-// getStructName 获取Hessian.POJO实现类的类名
+// getStructName gets the class name of the Hessian.POJO implementation
func getStructName(line []byte) []byte {
r, _ := regexp.Compile(HessianPOJONameRegexp)
line = r.Find(line)
@@ -163,7 +169,7 @@ func getStructName(line []byte) []byte {
return nil
}
-// genRegistryPOJOStatement 生成POJO注册方法体
+// genRegistryPOJOStatement generates the POJO registration statement
func genRegistryPOJOStatement(pojo []byte) []byte {
var buffer []byte
buffer = append(buffer, hessianRegistryPOJOFunctionPrefix...)
@@ -200,7 +206,7 @@ func escape(str string) string {
return str
}
-// genRegistryPOJOStatements 生成POJO注册方法体
+// genRegistryPOJOStatements generates POJO registration statements
// nolint
func genRegistryPOJOStatements(file *fileInfo, initFunctionStatement *[]byte)
[]byte {
f := file.path
@@ -210,7 +216,7 @@ func genRegistryPOJOStatements(file *fileInfo,
initFunctionStatement *[]byte) []
var rIndexList []int
for _, name := range hessianPOJOList {
statement := genRegistryPOJOStatement(name)
- if initFunctionStatement != nil { // 检测是否已存在注册方法体
+ if initFunctionStatement != nil { // Check whether a
registration statement already exists
r, _ = regexp.Compile(escape(string(statement)))
initStatement := *initFunctionStatement
rIndexList = r.FindIndex(initStatement)
@@ -218,9 +224,9 @@ func genRegistryPOJOStatements(file *fileInfo,
initFunctionStatement *[]byte) []
i := rIndexList[0]
n := lastIndexOf(initStatement, newLine, &i)
checkStatement :=
initStatement[lastIndexOf(initStatement, newLine, &n)+1 : i]
- if passed, _ := regexp.Match(LineCommentRegexp,
checkStatement); !passed { // 是否被行注释
+ if passed, _ := regexp.Match(LineCommentRegexp,
checkStatement); !passed { // Check if commented out
showLog(infoLog, "=== Ignore POJO
[%s].%s ===", f, name)
- continue // 忽略相同的注册操作
+ continue // Ignore duplicate
registration operations
}
}
}
@@ -242,7 +248,7 @@ func genRegistryStatement(file *fileInfo) error {
offset := 0
- if !file.hasHessianImport { // 追加hessian2导包
+ if !file.hasHessianImport { // Add hessian2 import statement
sliceIndex := file.packageEndIndex + offset
var bufferClone []byte
bufferClone = append(bufferClone, buffer[:sliceIndex]...)
@@ -260,17 +266,17 @@ func genRegistryStatement(file *fileInfo) error {
registryPOJOStatement = genRegistryPOJOStatements(file,
&initFunctionStatement)
var bufferClone []byte
bufferClone = append(bufferClone, buffer[:sliceIndex]...)
- bufferClone = append(bufferClone, registryPOJOStatement...) //
追加POJO注册方法体至init函数
+ bufferClone = append(bufferClone, registryPOJOStatement...) //
Append POJO registration statements into the init function
bufferClone = append(bufferClone, buffer[sliceIndex:]...)
buffer = bufferClone
- } else { // 追加初始化函数
+ } else { // Add init function
registryPOJOStatement = genRegistryPOJOStatements(file, nil)
- buffer = append(buffer, initFunctionPrefix...) // 添加init函数
- buffer = append(buffer, registryPOJOStatement...) //
追加POJO注册方法体至init函数
+ buffer = append(buffer, initFunctionPrefix...) // Add init
function
+ buffer = append(buffer, registryPOJOStatement...) // Append
POJO registration statements into init function
buffer = append(buffer, initFunctionSuffix...)
}
- f, err := os.OpenFile(file.path, os.O_CREATE|os.O_WRONLY, 0666)
+ f, err := os.OpenFile(file.path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC,
0666)
if err != nil {
return err
}