├── .github └── workflows │ ├── codeql-analysis.yml │ ├── gitee-sync.yml │ ├── go.yml │ └── reviewdog.yml ├── .gitignore ├── .golangci.yaml ├── .travis.yml ├── AUTHORS ├── CONTRIBUTING.md ├── Changelog.md ├── LICENSE ├── README.md ├── README.zh.md ├── contrib ├── gin │ ├── gin.go │ ├── go.mod │ └── go.sum ├── log │ ├── go.mod │ ├── go.sum │ ├── log.go │ ├── log_test.go │ └── logger.go └── middleware │ ├── opentelemetry │ ├── go.mod │ ├── go.sum │ ├── opentelemetry.go │ └── version.go │ └── zipkintracing │ ├── go.mod │ ├── go.sum │ └── zipkintracing.go ├── examples ├── CmakeServer │ ├── .gitignore │ ├── CMakeLists.txt │ ├── EchoTest.tars │ ├── EchoTestImp.go │ ├── EchoTestServer.conf │ ├── EchoTestServer.go │ ├── client │ │ ├── CMakeLists.txt │ │ └── client.go │ ├── go.mod │ └── start.sh ├── ContextTestServer │ ├── .gitignore │ ├── ContextTest.tars │ ├── ContextTestImp.go │ ├── ContextTestServer.conf │ ├── ContextTestServer.go │ ├── client │ │ └── client.go │ ├── debugtool │ │ └── dumpstack.go │ ├── go.mod │ ├── makefile │ └── start.sh ├── CustomProtoServer │ ├── .gitignore │ ├── CustomProtoImp.go │ ├── CustomProtoServer.conf │ ├── CustomProtoServer.go │ ├── client │ │ └── client.go │ ├── debugtool │ │ └── dumpstack.go │ ├── go.mod │ ├── makefile │ └── start.sh ├── EchoClientServer │ ├── .gitignore │ ├── EchoClient.tars │ ├── EchoClientServer.conf │ ├── EchoClientServer.go │ ├── EchoTest.tars │ ├── client │ │ └── client.go │ ├── go.mod │ ├── makefile │ └── start.sh ├── EchoTestServer │ ├── .gitignore │ ├── EchoTest.tars │ ├── EchoTestImp.go │ ├── EchoTestServer.conf │ ├── EchoTestServer.go │ ├── client │ │ └── client.go │ ├── go.mod │ ├── makefile │ └── start.sh ├── GinHttpServer │ ├── config.conf │ ├── go.mod │ ├── main.go │ ├── makefile │ └── start.sh ├── OpentelemetryServer │ ├── .gitignore │ ├── Opentelemetry.tars │ ├── OpentelemetryImp.go │ ├── OpentelemetryServer.conf │ ├── OpentelemetryServer.go │ ├── client │ │ └── client.go │ ├── debugtool │ │ └── dumpstack.go │ ├── docker-compose.yaml │ ├── go.mod │ ├── makefile │ ├── otel-collector-config.yaml │ ├── otel │ │ └── otel.go │ ├── prometheus.yaml │ └── start.sh ├── PushServer │ ├── .gitignore │ ├── client │ │ └── client.go │ ├── config.conf │ ├── debugtool │ │ └── dumpstack.go │ ├── main.go │ ├── makefile │ └── start.sh ├── Tars2Go │ ├── README.md │ ├── base │ │ └── demo1.tars │ ├── demo.tars │ └── go.mod ├── TlsTestServer │ ├── .gitignore │ ├── Tls.tars │ ├── Tls_imp.go │ ├── client │ │ └── client.go │ ├── config.conf │ ├── debugtool │ │ └── dumpstack.go │ ├── go.mod │ ├── main.go │ ├── makefile │ ├── scripts │ │ └── makefile.tars.gomod │ ├── start.sh │ └── tls.sh ├── trace │ ├── .gitignore │ ├── TarsTraceBackServer │ │ ├── Backend.tars │ │ ├── Backend_imp.go │ │ ├── client │ │ │ └── client.go │ │ ├── config.conf │ │ ├── debugtool │ │ │ └── dumpstack.go │ │ ├── go.mod │ │ ├── go.sum │ │ ├── main.go │ │ ├── makefile │ │ ├── scripts │ │ │ └── makefile.tars.gomod │ │ └── start.sh │ └── TarsTraceFrontServer │ │ ├── Frontend.tars │ │ ├── Frontend_imp.go │ │ ├── client │ │ └── client.go │ │ ├── config.conf │ │ ├── debugtool │ │ └── dumpstack.go │ │ ├── go.mod │ │ ├── go.sum │ │ ├── main.go │ │ ├── makefile │ │ ├── scripts │ │ └── makefile.tars.gomod │ │ └── start.sh └── zipkin │ ├── ZipkinTraceClient │ ├── .gitignore │ ├── ZipkinClient.tars │ ├── ZipkinClientImp.go │ ├── ZipkinTrace.tars │ ├── ZipkinTraceClient.conf │ ├── ZipkinTraceClient.go │ ├── client │ │ └── client.go │ ├── go.mod │ ├── makefile │ └── start.sh │ └── ZipkinTraceServer │ ├── .gitignore │ ├── ZipkinTrace.tars │ ├── ZipkinTraceImp.go │ ├── ZipkinTraceServer.conf │ ├── ZipkinTraceServer.go │ ├── client │ └── empty │ ├── go.mod │ ├── makefile │ └── start.sh ├── go.mod ├── go.sum ├── hack ├── cmake │ ├── CMakeDetermineGoCompiler.cmake │ ├── CMakeGoCompiler.cmake.in │ ├── CMakeGoInformation.cmake │ ├── CMakeTestGoCompiler.cmake │ ├── golang.cmake │ └── tars-tools.cmake ├── generate-authors.sh ├── generate-tarsgo.sh └── scripts │ ├── makefile.tars.gomod.mk │ └── makefile.tars.mk └── tars ├── .gitignore ├── adapter.go ├── admin.go ├── appcache.go ├── application.go ├── communicator.go ├── communicator_test.go ├── config.go ├── endpointmanager.go ├── errors.go ├── filter.go ├── hash_func.go ├── hash_func_test.go ├── httpserver.go ├── logger.go ├── message.go ├── model └── servant.go ├── nodef.go ├── notifyf.go ├── options.go ├── panic.go ├── propertyf.go ├── protocol ├── codec │ ├── codec.go │ └── codec_test.go ├── protoconst.go ├── push │ ├── client.go │ └── server.go ├── res │ ├── AdminF.tars │ ├── AuthF.tars │ ├── BaseF.tars │ ├── ConfigF.tars │ ├── EndpointF.tars │ ├── LogF.tars │ ├── Makefile │ ├── NodeF.tars │ ├── NotifyF.tars │ ├── PropertyF.tars │ ├── QueryF.tars │ ├── RequestF.tars │ ├── StatF.tars │ ├── adminf │ │ └── AdminF.tars.go │ ├── authf │ │ ├── Auth.tars.go │ │ └── AuthF.go │ ├── basef │ │ └── BaseF.go │ ├── configf │ │ ├── Config.tars.go │ │ └── ConfigF.go │ ├── endpointf │ │ └── EndpointF.go │ ├── logf │ │ ├── Log.tars.go │ │ └── LogF.go │ ├── nodef │ │ ├── NodeF.go │ │ └── ServerF.tars.go │ ├── notifyf │ │ ├── Notify.tars.go │ │ └── NotifyF.go │ ├── propertyf │ │ ├── PropertyF.go │ │ └── PropertyF.tars.go │ ├── queryf │ │ └── QueryF.tars.go │ ├── requestf │ │ ├── RequestF.go │ │ └── request.go │ └── statf │ │ ├── StatF.go │ │ └── StatF.tars.go ├── tarsprotocol.go ├── tarsprotocol_test.go └── tup │ └── tup.go ├── rconfig.go ├── registry.go ├── registry ├── registry.go └── tars │ └── registry.go ├── remotelogger.go ├── selector ├── consistenthash │ ├── consistenthash_new.go │ └── consistenthash_new_test.go ├── modhash │ └── modhash.go ├── random │ └── random.go ├── roundrobin │ ├── round_robin.go │ └── round_robin_test.go └── selector.go ├── servant.go ├── servanthandle.go ├── setting.go ├── statf.go ├── tarsprotocol.go ├── tools ├── pb2tarsgo │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── protoc-gen-go │ │ ├── link_tarsrpc.go │ │ ├── main.go │ │ └── tarsrpc │ │ └── tarsrpc.go ├── protoc-gen-go-tarsrpc │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── tarsrpc.go ├── tars2go │ ├── ast │ │ └── ast.go │ ├── gencode │ │ └── gen_go.go │ ├── go.mod │ ├── lexer │ │ └── lexer.go │ ├── main.go │ ├── options │ │ └── options.go │ ├── parse │ │ └── parse.go │ ├── token │ │ └── token.go │ ├── utils │ │ └── utils.go │ └── version │ │ └── version.go └── tarsgo │ ├── .gitignore │ ├── README_ZH.md │ ├── go.mod │ ├── go.sum │ ├── internal │ ├── base │ │ ├── args.go │ │ ├── install.go │ │ ├── install_compatible.go │ │ ├── mod.go │ │ ├── mod_test.go │ │ ├── path.go │ │ ├── project.go │ │ ├── repo.go │ │ ├── repo_test.go │ │ └── templates.go │ ├── bindata │ │ └── bindata.go │ ├── cmake │ │ └── cmake.go │ ├── consts │ │ ├── makefile.go │ │ └── version.go │ ├── make │ │ └── make.go │ └── upgrade │ │ ├── cmake.go │ │ ├── make.go │ │ └── upgrade.go │ └── main.go ├── transport.go ├── transport ├── _examples │ ├── helloserver │ │ ├── client.go │ │ └── server.go │ └── udpserver │ │ ├── client.go │ │ └── server.go ├── common.go ├── tarsclient.go ├── tarsserver.go ├── tcphandler.go └── udphandler.go └── util ├── conf ├── MMGR.TestServer.conf ├── conf.go └── conf_test.go ├── current ├── clientcurrent.go └── tarscurrent.go ├── debug ├── debugtool.go └── debugtool_test.go ├── endpoint ├── convert.go ├── endpoint.go ├── parse.go └── parse_test.go ├── gpool ├── gpool.go ├── gpool_benchmark_test.go └── gpool_test.go ├── grace ├── grace.go ├── grace_test.go ├── signal_unix.go └── signal_windows.go ├── gtime ├── gtime.go └── gtime_test.go ├── rogger ├── dyeing.go ├── logger.go ├── logger_test.go └── logwriter.go ├── rtimer ├── timewheel.go └── timewheel_test.go ├── set ├── set.go └── set_test.go ├── ssl └── ssl.go ├── sync └── once.go ├── tools ├── convert.go ├── ip.go ├── parser.go ├── unique.go └── upperbound.go └── trace ├── id_generator.go └── trace.go /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | schedule: 9 | - cron: '20 20 * * 6' 10 | jobs: 11 | analyze: 12 | name: Analyze 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout repo 17 | uses: actions/checkout@v2 18 | 19 | - name: Initialize CodeQL 20 | uses: github/codeql-action/init@v1 21 | with: 22 | languages: go 23 | 24 | - name: Autobuild 25 | uses: github/codeql-action/autobuild@v1 26 | 27 | - name: CodeQL Analysis 28 | uses: github/codeql-action/analyze@v1 -------------------------------------------------------------------------------- /.github/workflows/gitee-sync.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | tags: 6 | - "*" 7 | 8 | name: Sync to Gitee 9 | jobs: 10 | run: 11 | name: Run 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout source code 15 | uses: actions/checkout@v1 16 | - name: Mirror Github to Gitee 17 | uses: Yikun/hub-mirror-action@v1.2 18 | with: 19 | src: github/TarsCloud 20 | dst: gitee/TarsCloud 21 | dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} 22 | dst_token: ${{ secrets.GITEE_TOKEN }} 23 | account_type: org 24 | timeout: 600 25 | debug: true 26 | force_update: true 27 | static_list: "TarsGo" -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | name: build & test 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Set up Go 1.x 16 | uses: actions/setup-go@v2 17 | with: 18 | go-version: ^1.16 19 | id: go 20 | 21 | - name: Check out code into the Go module directory 22 | uses: actions/checkout@v2 23 | 24 | - name: tars2go 25 | run: | 26 | cd tars/tools/tars2go 27 | go build ./... 28 | go test ./... 29 | 30 | - name: tarsgo 31 | run: | 32 | cd tars/tools/tarsgo 33 | go build ./... 34 | go test ./... 35 | 36 | - name: Build 37 | run: | 38 | go mod tidy 39 | go build ./tars 40 | 41 | - name: Codecov 42 | uses: codecov/codecov-action@v2 43 | -------------------------------------------------------------------------------- /.github/workflows/reviewdog.yml: -------------------------------------------------------------------------------- 1 | name: reviewdog 2 | on: [pull_request] 3 | jobs: 4 | golangci-lint: 5 | runs-on: ubuntu-latest 6 | name: runner / golangci-lint 7 | steps: 8 | - name: Check out code into the Go module directory 9 | uses: actions/checkout@v3 10 | - name: golangci-lint 11 | uses: reviewdog/action-golangci-lint@v2 12 | with: 13 | github_token: ${{ secrets.github_token }} 14 | # Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review]. 15 | reporter: github-pr-review 16 | # Report all results. 17 | filter_mode: nofilter 18 | # Exit with 1 when it finds at least one finding. 19 | fail_on_error: true 20 | #golangci_lint_flags -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | *.tar.gz 4 | *.tgz 5 | tars-protocol 6 | examples/*/go.sum 7 | .DS_Store -------------------------------------------------------------------------------- /.golangci.yaml: -------------------------------------------------------------------------------- 1 | run: 2 | timeout: 30m 3 | skip-dirs: 4 | - tars/protocol/res 5 | 6 | linters: 7 | disable-all: true 8 | enable: 9 | - unused 10 | - ineffassign 11 | - goimports 12 | - gofmt 13 | - misspell 14 | - unparam 15 | - unconvert 16 | - govet 17 | # - errcheck 18 | - staticcheck 19 | 20 | linters-settings: 21 | staticcheck: 22 | go: "1.17" 23 | checks: 24 | - "all" 25 | # TODO(fix) Using a deprecated function, variable, constant or field 26 | - "-SA1019" 27 | 28 | unused: 29 | go: "1.17" 30 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - '1.9' 4 | - 1.10.x 5 | - 1.11.x 6 | - 1.12.x 7 | - 1.13.x 8 | - 1.14.x 9 | - 1.15.x 10 | - 1.16.x 11 | - 1.17.x 12 | - 1.18.x 13 | - 1.19.x 14 | - 1.20.x 15 | install: 16 | - echo "$GOPATH" 17 | script: 18 | - go build github.com/TarsCloud/TarsGo/tars -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This file lists all individuals having contributed content to the repository. 2 | # For how it is generated, see `hack/generate-authors.sh`. 3 | 4 | 0xflotus <0xflotus@gmail.com> 5 | CHAO YIN 6 | Chen Mingjie 7 | ChenMingjie <15210875043@sina.cn> 8 | Defoo Li 9 | Erjan Kalybek 10 | Jiechao Wu 11 | Michael Henderson 12 | MonkeyLi 13 | Nick Wanninger 14 | Ramon Barros 15 | rikewang 16 | sandyskies 17 | TauWoo 18 | Terry Ding 19 | Tim Xu 20 | titustian 21 | xuri 22 | YaffaBeauty <30791158+YaffaBeauty@users.noreply.github.com> 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to TarsGo 2 | 3 | ## 0 All pull request must go to dev branch, not master. 4 | All pull request must use dev branch as base branch, not master , master is used for publishing. 5 | 6 | ## 1 Create an issue 7 | Use English as u can. 8 | 9 | if you want to report a bug, use this template in issue: 10 | ``` 11 | **Describe the bug** 12 | A clear and concise description of what the bug is. 13 | 14 | **To Reproduce** 15 | Steps to reproduce the behavior: 16 | 17 | ** Version info 18 | Which go version : 19 | Which tars version (git commit id or branch name): 20 | Which os: 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | **Additional context** 26 | Add any other context about the problem here. 27 | ``` 28 | if you want to propose a feature ,use this template in issue : 29 | ``` 30 | **Is your feature request related to a problem? Please describe.** 31 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 32 | 33 | **Describe the solution you'd like** 34 | A clear and concise description of what you want to happen. 35 | 36 | **Describe alternatives you've considered** 37 | A clear and concise description of any alternative solutions or features you've considered. 38 | 39 | **Additional context** 40 | Add any other context or screenshots about the feature request here. 41 | 42 | ``` 43 | 44 | ## 2 Fork the project 45 | click the fork button on the right top of the project. 46 | ![fork button](docs/images/fork_button.png) 47 | 48 | ## 3 Create a pull request 49 | if you want to create a pull request, you must create a issue first. 50 | In the pr, you should give the related issue. 51 | All pull request must go to dev branch, not master. 52 | 53 | ## 4 Code standards 54 | ALL go file must be formated by gofmt and must be fixed after golint. 55 | 56 | 57 | ## 5 Create pull request 58 | 59 | Please feel free to create request in github for TarsGo. 60 | 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, THE TARS FOUNDATION 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TarsGo 2 | 3 | English | [简体中文](README.zh.md) 4 | 5 | - Document:[TarsGo Document](https://doc.tarsyun.com/#/dev/tarsgo/README.md) 6 | - Twitter: [@TarsCloud](https://twitter.com/TarsCloud) 7 | - [Mailing List](https://groups.google.com/g/tars-foundation-information) 8 | 9 | ## About 10 | 11 | - TarsGo is high performance RPC framework in Golang programing language using the tars protocol. 12 | - Go has become popular for programming with the rise of containerization technology such as docker, k8s, and etcd. 13 | - Go's goroutine concurrency mechanism means Go is very suitable for large-scale high-concurrency back-end server program development. The Go language has nearly C/C++ performance and near Python productivity. 14 | - In Tencent, part of the existing C++ development team has gradually turned into Go developers. Tars, a widely used RPC framework, supports C++, Java, NodeJS, and PHP, and now Go. The combination with Go language has become a general trend. Therefore, in the voice of users, we launched TarsGo, and we have applied to Tencent map application, YingYongbao application, Internet plus and other projects. 15 | - Learn more about the whole Tars architecture and design at [Introduction](https://doc.tarsyun.com/#/base/tars-intro.md). 16 | 17 | ## Quick start 18 | 19 | [Quick Start Guide](https://doc.tarsyun.com/#/hello-world/tarsgo.md). 20 | 21 | ## How to Contribute 22 | 23 | [Contribution Guide](CONTRIBUTING.md). 24 | -------------------------------------------------------------------------------- /README.zh.md: -------------------------------------------------------------------------------- 1 | # TarsGo 2 | 3 | [English](README.md) | 简体中文 4 | - 文档主页:[https://doc.tarsyun.com/](https://doc.tarsyun.com/#/dev/tarsgo/README.md) 5 | - Twitter: [@TarsCloud](https://twitter.com/TarsCloud) 6 | - [Mailing List](https://groups.google.com/g/tars-foundation-information) 7 | - [官网](http://tarscloud.org/) 8 | - [新闻](https://tarscloud.org/feed/newsroom) 9 | - QQ 技术交流群群:515945105, 579079160(满), 669339903(满) 10 | - 微信公众号: TarsCloud 11 | - 微信 ID: TARS01 12 | - [联系我们](https://tarscloud.org/about/contacts) 13 | 14 | ## 关于 15 | 16 | - TarsGo是基于Golang编程语言使用Tars协议的高性能RPC框架。随着docker,k8s,etcd等容器化技术的兴起,Go语言变得流行起来。Go的goroutine并发机制使Go非常适合用于大规模高并发后端服务程序的开发。 Go语言具有接近C/C++的性能和接近python的生产力。在腾讯,一部分现有的C++开发人员正逐渐向Go转型,Tars作为广泛使用的RPC框架,现已支持C++/Java/Nodejs/Php,其与Go语言的结合已成为大势所趋。因此,在广大用户的呼声中我们推出了Tarsgo,并且已经将它应用于腾讯地图、应用宝、互联网+以及其他项目中。 17 | - 关于Tars的整体架构和设计理念,请阅读 [Tars官方文档](https://doc.tarsyun.com/#/base/tars-intro.md)。 18 | 19 | ## 快速开始 20 | 21 | 请查看[相关文档](https://doc.tarsyun.com/#/hello-world/tarsgo.md)。 22 | 23 | ## 如何贡献 24 | 25 | 请先阅读[说明文档](CONTRIBUTING.md)。 -------------------------------------------------------------------------------- /contrib/gin/gin.go: -------------------------------------------------------------------------------- 1 | package gin 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strings" 7 | "time" 8 | 9 | "github.com/TarsCloud/TarsGo/tars" 10 | "github.com/TarsCloud/TarsGo/tars/protocol/res/statf" 11 | "github.com/gin-gonic/gin" 12 | ) 13 | 14 | type ServerOption func(*Server) 15 | 16 | type Server struct { 17 | *gin.Engine 18 | cfg *tars.TarsHttpConf 19 | } 20 | 21 | var _ tars.HttpHandler = (*Server)(nil) 22 | 23 | func New(opts ...ServerOption) *Server { 24 | s := &Server{ 25 | Engine: gin.Default(), 26 | } 27 | for _, opt := range opts { 28 | opt(s) 29 | } 30 | s.middleware() 31 | return s 32 | } 33 | 34 | func (g *Server) middleware() { 35 | g.Use(func(c *gin.Context) { 36 | startTime := time.Now() 37 | if c.Request.RequestURI == "*" { 38 | if c.Request.ProtoAtLeast(1, 1) { 39 | c.Header("Connection", "close") 40 | } 41 | c.AbortWithStatus(http.StatusBadRequest) 42 | return 43 | } 44 | c.Next() 45 | costTime := time.Since(startTime).Milliseconds() 46 | go g.reportHttpStat(c.ClientIP(), c.FullPath(), c.Writer.Status(), costTime) 47 | }) 48 | } 49 | 50 | func (g *Server) SetConfig(cfg *tars.TarsHttpConf) { 51 | g.cfg = cfg 52 | } 53 | 54 | func (g *Server) reportHttpStat(clientIP, pattern string, statusCode int, costTime int64) { 55 | if g.cfg == nil { 56 | return 57 | } 58 | cfg := g.cfg 59 | var statInfo = statf.StatMicMsgHead{} 60 | statInfo.MasterName = "http_client" 61 | statInfo.MasterIp = clientIP 62 | 63 | statInfo.TarsVersion = cfg.Version 64 | statInfo.SlaveName = cfg.AppName 65 | statInfo.SlaveIp = cfg.IP // from server 66 | statInfo.SlavePort = cfg.Port 67 | statInfo.InterfaceName = pattern 68 | if cfg.SetId != "" { 69 | setList := strings.Split(cfg.SetId, ".") 70 | statInfo.SlaveSetName = setList[0] 71 | statInfo.SlaveSetArea = setList[1] 72 | statInfo.SlaveSetID = setList[2] 73 | //被调也要加上set信息 74 | statInfo.SlaveName = fmt.Sprintf("%s.%s%s%s", statInfo.SlaveName, setList[0], setList[1], setList[2]) 75 | } 76 | 77 | var statBody = statf.StatMicMsgBody{} 78 | exceptionChecker := g.cfg.ExceptionStatusChecker 79 | if exceptionChecker == nil { 80 | // if nil, use default 81 | exceptionChecker = tars.DefaultExceptionStatusChecker 82 | } 83 | if exceptionChecker(statusCode) { 84 | statBody.ExecCount = 1 // 异常 85 | } else { 86 | statBody.Count = 1 87 | statBody.TotalRspTime = costTime 88 | statBody.MaxRspTime = int32(costTime) 89 | statBody.MinRspTime = int32(costTime) 90 | } 91 | 92 | tars.ReportStatBase(&statInfo, &statBody, true) 93 | } 94 | -------------------------------------------------------------------------------- /contrib/gin/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/contrib/gin 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.4 7 | github.com/gin-gonic/gin v1.9.1 8 | ) 9 | 10 | require ( 11 | github.com/bytedance/sonic v1.9.1 // indirect 12 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 13 | github.com/gabriel-vasile/mimetype v1.4.2 // indirect 14 | github.com/gin-contrib/sse v0.1.0 // indirect 15 | github.com/go-playground/locales v0.14.1 // indirect 16 | github.com/go-playground/universal-translator v0.18.1 // indirect 17 | github.com/go-playground/validator/v10 v10.14.0 // indirect 18 | github.com/goccy/go-json v0.10.2 // indirect 19 | github.com/json-iterator/go v1.1.12 // indirect 20 | github.com/klauspost/cpuid/v2 v2.2.4 // indirect 21 | github.com/leodido/go-urn v1.2.4 // indirect 22 | github.com/mattn/go-isatty v0.0.19 // indirect 23 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 24 | github.com/modern-go/reflect2 v1.0.2 // indirect 25 | github.com/pelletier/go-toml/v2 v2.0.8 // indirect 26 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 27 | github.com/ugorji/go/codec v1.2.11 // indirect 28 | go.uber.org/automaxprocs v1.5.2 // indirect 29 | golang.org/x/arch v0.3.0 // indirect 30 | golang.org/x/crypto v0.9.0 // indirect 31 | golang.org/x/net v0.10.0 // indirect 32 | golang.org/x/sys v0.8.0 // indirect 33 | golang.org/x/text v0.9.0 // indirect 34 | google.golang.org/protobuf v1.30.0 // indirect 35 | gopkg.in/yaml.v3 v3.0.1 // indirect 36 | ) 37 | -------------------------------------------------------------------------------- /contrib/log/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/contrib/log 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.4 7 | go.opentelemetry.io/otel/trace v1.14.0 8 | ) 9 | 10 | require ( 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/go-logr/logr v1.2.3 // indirect 13 | github.com/go-logr/stdr v1.2.2 // indirect 14 | github.com/pmezard/go-difflib v1.0.0 // indirect 15 | go.opentelemetry.io/otel v1.14.0 // indirect 16 | go.uber.org/automaxprocs v1.5.2 // indirect 17 | golang.org/x/sys v0.5.0 // indirect 18 | gopkg.in/yaml.v3 v3.0.1 // indirect 19 | ) 20 | 21 | require ( 22 | github.com/stretchr/testify v1.8.4 23 | go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0 24 | go.opentelemetry.io/otel/sdk v1.14.0 25 | ) 26 | -------------------------------------------------------------------------------- /contrib/log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | ) 8 | 9 | // GetLogger Get a logger 10 | func GetLogger(name string) *Logger { 11 | logPath, lg := getLogger(name) 12 | // if the default writer is not ConsoleWriter, the writer has already been configured 13 | if !lg.IsConsoleWriter() { 14 | return lg 15 | } 16 | if logPath == "" { 17 | return lg 18 | } 19 | cfg := tars.GetServerConfig() 20 | lg.SetFileRoller(logPath, int(cfg.LogNum), int(cfg.LogSize)) 21 | return lg 22 | } 23 | 24 | func getLogger(name string) (logPath string, lg *Logger) { 25 | cfg := tars.GetServerConfig() 26 | if cfg == nil { 27 | return "", GetCtxLogger(name) 28 | } 29 | if name == "" { 30 | name = cfg.App + "." + cfg.Server 31 | } else { 32 | name = cfg.App + "." + cfg.Server + "_" + name 33 | } 34 | logPath = filepath.Join(cfg.LogPath, cfg.App, cfg.Server) 35 | lg = GetCtxLogger(name) 36 | return logPath, lg 37 | } 38 | 39 | // GetDayLogger Get a logger roll by day 40 | func GetDayLogger(name string, numDay int) *Logger { 41 | logPath, lg := getLogger(name) 42 | // if the default writer is not ConsoleWriter, the writer has already been configured 43 | if !lg.IsConsoleWriter() { 44 | return lg 45 | } 46 | lg.SetDayRoller(logPath, numDay) 47 | return lg 48 | } 49 | 50 | // GetHourLogger Get a logger roll by hour 51 | func GetHourLogger(name string, numHour int) *Logger { 52 | logPath, lg := getLogger(name) 53 | // if the default writer is not ConsoleWriter, the writer has already been configured 54 | if !lg.IsConsoleWriter() { 55 | return lg 56 | } 57 | lg.SetHourRoller(logPath, numHour) 58 | return lg 59 | } 60 | 61 | // GetRemoteLogger returns a remote logger 62 | func GetRemoteLogger(name string) *Logger { 63 | cfg := tars.GetServerConfig() 64 | lg := GetCtxLogger(name) 65 | if !lg.IsConsoleWriter() { 66 | return lg 67 | } 68 | remoteWriter := tars.NewRemoteTimeWriter() 69 | var set string 70 | if cfg.Enableset { 71 | set = cfg.Setdivision 72 | } 73 | 74 | remoteWriter.InitServerInfo(cfg.App, cfg.Server, name, set) 75 | lg.SetWriter(remoteWriter) 76 | return lg 77 | } 78 | -------------------------------------------------------------------------------- /contrib/middleware/opentelemetry/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/contrib/middleware/opentelemetry 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.4 7 | go.opentelemetry.io/otel v1.15.0-rc.1 8 | go.opentelemetry.io/otel/metric v1.15.0-rc.1 9 | go.opentelemetry.io/otel/trace v1.15.0-rc.1 10 | ) 11 | 12 | require ( 13 | github.com/go-logr/logr v1.2.3 // indirect 14 | github.com/go-logr/stdr v1.2.2 // indirect 15 | go.uber.org/automaxprocs v1.5.2 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /contrib/middleware/opentelemetry/version.go: -------------------------------------------------------------------------------- 1 | package opentelemetry 2 | 3 | // Version is the current release version of the TarsGo instrumentation. 4 | func Version() string { 5 | return "0.0.1-rc.1" 6 | // This string is updated by the pre_release.sh script during release 7 | } 8 | 9 | // SemVersion is the semantic version to be supplied to tracer/meter creation. 10 | func SemVersion() string { 11 | return "semver:" + Version() 12 | } 13 | -------------------------------------------------------------------------------- /contrib/middleware/zipkintracing/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/contrib/middleware/zipkintracing 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.4 7 | github.com/opentracing/opentracing-go v1.2.0 8 | github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0 9 | github.com/openzipkin/zipkin-go v0.4.1 10 | ) 11 | -------------------------------------------------------------------------------- /examples/CmakeServer/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | cmake 3 | -------------------------------------------------------------------------------- /examples/CmakeServer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | execute_process(COMMAND go env GOPATH OUTPUT_VARIABLE GOPATH) 3 | string(REGEX REPLACE "\n$" "" GOPATH "${GOPATH}") 4 | 5 | include(cmake/tars-tools.cmake) 6 | 7 | cmake_minimum_required(VERSION 2.8) 8 | 9 | project(CmakeServer Go) # select GO compile 10 | 11 | add_subdirectory(client) 12 | 13 | gen_server(StressTest CmakeServer) 14 | 15 | 16 | # go mod init 17 | # mkdir build 18 | # cd build 19 | # cmake .. 20 | # make -------------------------------------------------------------------------------- /examples/CmakeServer/EchoTest.tars: -------------------------------------------------------------------------------- 1 | module StressTest{ 2 | interface EchoTest{ 3 | int echo(vector sIn, out vector sOut); 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /examples/CmakeServer/EchoTestImp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //EchoTestImp struct 4 | type EchoTestImp struct { 5 | } 6 | 7 | //Echo implement 8 | func (imp *EchoTestImp) Echo(b []int8, c *[]int8) (int32, error) { 9 | *c = b 10 | return 0, nil 11 | } 12 | -------------------------------------------------------------------------------- /examples/CmakeServer/EchoTestServer.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=StressTest 5 | server=EchoTestServer 6 | local=tcp -h 127.0.0.1 -p 10014 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 10015 -t 60000 11 | handlegroup=StressTest.EchoTestServer.EchoTestObjAdapter 12 | maxconns=200000 13 | protocol=tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=StressTest.EchoTestServer.EchoTestObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/CmakeServer/EchoTestServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/TarsCloud/TarsGo/tars" 8 | 9 | "CmakeServer/tars-protocol/StressTest" 10 | "runtime/pprof" 11 | ) 12 | 13 | func main() { //Init servant 14 | f, err := os.Create("/usr/local/app/tars/app_log/cpu.profile") 15 | if err != nil { 16 | log.Fatal("could not create CPU profile: ", err) 17 | } 18 | if err := pprof.StartCPUProfile(f); err != nil { 19 | log.Fatal("could not start CPU profile: ", err) 20 | } 21 | defer pprof.StopCPUProfile() 22 | 23 | imp := new(EchoTestImp) //New Imp 24 | app := new(StressTest.EchoTest) //New init the A JCE 25 | cfg := tars.GetServerConfig() //Get Config File Object 26 | app.AddServant(imp, cfg.App+"."+cfg.Server+".EchoTestObj") //Register Servant 27 | tars.Run() 28 | 29 | // log.Fatal("succ") 30 | } 31 | -------------------------------------------------------------------------------- /examples/CmakeServer/client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 2.8) 3 | 4 | project(Client Go) # select GO compile 5 | 6 | gen_server(StressTest Client) 7 | 8 | 9 | # go mod init 10 | # mkdir build 11 | # cd build 12 | # cmake .. 13 | # make -------------------------------------------------------------------------------- /examples/CmakeServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | 8 | "CmakeServer/tars-protocol/StressTest" 9 | ) 10 | 11 | func main() { 12 | comm := tars.GetCommunicator() 13 | obj := fmt.Sprintf("StressTest.EchoTestServer.EchoTestObj@tcp -h 127.0.0.1 -p 10015 -t 60000") 14 | app := new(StressTest.EchoTest) 15 | comm.StringToProxy(obj, app) 16 | var out, i []int8 17 | i = []int8{5, 2, 0} 18 | ret, err := app.Echo(i, &out) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | fmt.Println(ret, out) 24 | } 25 | -------------------------------------------------------------------------------- /examples/CmakeServer/go.mod: -------------------------------------------------------------------------------- 1 | module CmakeServer 2 | 3 | go 1.14 4 | 5 | require github.com/TarsCloud/TarsGo v0.0.0 6 | 7 | replace github.com/TarsCloud/TarsGo => ../../ 8 | -------------------------------------------------------------------------------- /examples/CmakeServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp -rf ../../hack/cmake . 4 | mkdir build 5 | cd build 6 | cmake .. 7 | make 8 | cd - 9 | ./build/bin/CmakeServer --config=EchoTestServer.conf 10 | -------------------------------------------------------------------------------- /examples/ContextTestServer/.gitignore: -------------------------------------------------------------------------------- 1 | ContextTestServer 2 | -------------------------------------------------------------------------------- /examples/ContextTestServer/ContextTest.tars: -------------------------------------------------------------------------------- 1 | module StressTest{ 2 | interface ContextTest{ 3 | int Add(int a,int b,out int c); // Some example function 4 | int Sub(int a,int b,out int c); // Some example function 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /examples/ContextTestServer/ContextTestImp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | 8 | "github.com/TarsCloud/TarsGo/tars/util/current" 9 | ) 10 | 11 | type ContextTestImp struct { 12 | } 13 | 14 | func (imp *ContextTestImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 15 | if a == 1111 { 16 | return 0, tars.Errorf(1111, "Error occurred, code: %d", 1919) 17 | } 18 | 19 | logger := tars.GetLogger("context") 20 | ip, ok := current.GetClientIPFromContext(ctx) 21 | if !ok { 22 | logger.Error("Error getting ip from context") 23 | } 24 | logger.Infof("Get Client Ip : %s from context", ip) 25 | reqContext, ok := current.GetRequestContext(ctx) 26 | if !ok { 27 | logger.Error("Error getting reqcontext from context") 28 | } 29 | logger.Infof("Get context from context: %v", reqContext) 30 | k := make(map[string]string) 31 | k["resp"] = "respform context" 32 | ok = current.SetResponseContext(ctx, k) 33 | if !ok { 34 | logger.Error("error setting respose context") 35 | } 36 | //Doing something in your function 37 | //... 38 | *c = a * b 39 | return 0, nil 40 | } 41 | func (imp *ContextTestImp) Sub(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 42 | //Doing something in your function 43 | //... 44 | return 0, nil 45 | } 46 | -------------------------------------------------------------------------------- /examples/ContextTestServer/ContextTestServer.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=StressTest 5 | server=ContextTestServer 6 | local=tcp -h 127.0.0.1 -p 10027 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 10028 -t 60000 11 | handlegroup=StressTest.ContextTestServer.ContextTestObjAdapter 12 | maxconns=200000 13 | protocol=tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=StressTest.ContextTestServer.ContextTestObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/ContextTestServer/ContextTestServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/TarsCloud/TarsGo/tars" 5 | 6 | "ContextTestServer/tars-protocol/StressTest" 7 | "log" 8 | "net/http" 9 | _ "net/http/pprof" 10 | ) 11 | 12 | func main() { //Init servant 13 | go func() { 14 | log.Fatal(http.ListenAndServe("0.0.0.0:8090", nil)) 15 | }() 16 | 17 | imp := new(ContextTestImp) //New Imp 18 | app := new(StressTest.ContextTest) //New init the A Tars 19 | cfg := tars.GetServerConfig() //Get Config File Object 20 | app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".ContextTestObj") //Register Servant 21 | tars.Run() 22 | } 23 | -------------------------------------------------------------------------------- /examples/ContextTestServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/TarsCloud/TarsGo/tars" 8 | 9 | "ContextTestServer/tars-protocol/StressTest" 10 | ) 11 | 12 | func main() { 13 | comm := tars.GetCommunicator() 14 | obj := fmt.Sprintf("StressTest.ContextTestServer.ContextTestObj@tcp -h 127.0.0.1 -p 10028 -t 60000") 15 | app := new(StressTest.ContextTest) 16 | comm.StringToProxy(obj, app) 17 | var out, i int32 18 | i = 1111 19 | ctx := context.Background() 20 | c := make(map[string]string) 21 | c["a"] = "b" 22 | ret, err := app.AddWithContext(ctx, i, i*2, &out, c) 23 | if code := tars.GetErrorCode(err); code != 0 { 24 | fmt.Printf("error code: %d, message %v\n", code, err) 25 | return 26 | } 27 | fmt.Println(c) 28 | fmt.Println(ret, out) 29 | } 30 | -------------------------------------------------------------------------------- /examples/ContextTestServer/debugtool/dumpstack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/TarsCloud/TarsGo/tars" 6 | "github.com/TarsCloud/TarsGo/tars/protocol/res/adminf" 7 | ) 8 | 9 | func main() { 10 | comm := tars.GetCommunicator() 11 | obj := fmt.Sprintf("StressTest.ContextTestServer.ContextTestObjObj@tcp -h 127.0.0.1 -p 10014 -t 60000") 12 | app := new(adminf.AdminF) 13 | comm.StringToProxy(obj, app) 14 | ret, err := app.Notify("tars.dumpstack") 15 | if err != nil { 16 | fmt.Println(err) 17 | return 18 | } 19 | fmt.Println(ret) 20 | } 21 | -------------------------------------------------------------------------------- /examples/ContextTestServer/go.mod: -------------------------------------------------------------------------------- 1 | module ContextTestServer 2 | 3 | go 1.14 4 | 5 | require github.com/TarsCloud/TarsGo v0.0.0 6 | 7 | replace github.com/TarsCloud/TarsGo => ../../ 8 | -------------------------------------------------------------------------------- /examples/ContextTestServer/makefile: -------------------------------------------------------------------------------- 1 | APP := StressTest 2 | TARGET := ContextTestServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk -------------------------------------------------------------------------------- /examples/ContextTestServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./ContextTestServer --config=ContextTestServer.conf 4 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/.gitignore: -------------------------------------------------------------------------------- 1 | CustomProtoServer 2 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/CustomProtoImp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "fmt" 7 | "net/url" 8 | "strings" 9 | 10 | "github.com/TarsCloud/TarsGo/tars/transport" 11 | ) 12 | 13 | // CustomProtocolImp str protocol object implements ServerProtocol interface 14 | type CustomProtocolImp struct { 15 | } 16 | 17 | func (s *CustomProtocolImp) GetCloseMsg() []byte { 18 | return nil 19 | } 20 | 21 | func (s *CustomProtocolImp) DoClose(ctx context.Context) { 22 | } 23 | 24 | // ParsePackage parse request package 25 | func (s *CustomProtocolImp) ParsePackage(buff []byte) (int, int) { 26 | if len(buff) < 4 { 27 | return 0, transport.PackageLess 28 | } 29 | if len(buff) > 10485760 { 30 | return 0, transport.PackageError 31 | } 32 | var idx = bytes.Index(buff, []byte("\n")) 33 | if idx > 0 { 34 | return idx + 1, transport.PackageFull 35 | } 36 | 37 | return 0, transport.PackageLess 38 | } 39 | 40 | // Invoke process request and send response 41 | func (s *CustomProtocolImp) Invoke(ctx context.Context, req []byte) []byte { 42 | fmt.Print("req:", string(req)) 43 | reqMap, err := url.ParseQuery(strings.TrimSpace(string(req))) 44 | if err != nil { 45 | return []byte("ret=-1&msg=invalid_format\n") 46 | } 47 | 48 | cmd := reqMap.Get("cmd") 49 | data := reqMap.Get("data") 50 | if cmd == "hello" { 51 | return []byte(fmt.Sprintf("ret=%d&data=hello,%s\n", 0, data)) 52 | } else if cmd == "echo" { 53 | return []byte(fmt.Sprintf("ret=%d&data=%s\n", 0, data)) 54 | } else { 55 | return []byte(fmt.Sprintf("ret=%d&data=%s\n", -1, "invalid cmd")) 56 | } 57 | } 58 | 59 | // InvokeTimeout send response when server is timeout 60 | func (s *CustomProtocolImp) InvokeTimeout(pkg []byte) []byte { 61 | fmt.Println("invoke timeout:", pkg) 62 | rsp := bytes.NewBuffer(nil) 63 | rsp.WriteString("ret=-1&data=timeout\n") 64 | return rsp.Bytes() 65 | } 66 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/CustomProtoServer.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=Test 5 | server=CustomProtoServer 6 | local=tcp -h 127.0.0.1 -p 11027 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 11028 -t 60000 11 | handlegroup=Test.CustomProtoServer.CustomProtoObjAdapter 12 | maxconns=200000 13 | protocol=not_tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=Test.CustomProtoServer.CustomProtoObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/CustomProtoServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/TarsCloud/TarsGo/tars" 5 | ) 6 | 7 | func main() { //Init servant 8 | cfg := tars.GetServerConfig() //Get Config File Object 9 | proto := new(CustomProtocolImp) //New Proto 10 | tars.AddServantWithProtocol(proto, cfg.App+"."+cfg.Server+".CustomProtoObj") //Register Servant 11 | tars.Run() 12 | } 13 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "strconv" 7 | "time" 8 | 9 | "github.com/TarsCloud/TarsGo/tars/transport" 10 | ) 11 | 12 | type MyClient struct { 13 | recvCount int 14 | } 15 | 16 | func (c *MyClient) Recv(pkg []byte) { 17 | fmt.Print("recv:", string(pkg)) 18 | c.recvCount++ 19 | } 20 | func (c *MyClient) ParsePackage(buff []byte) (pkgLen, status int) { 21 | if len(buff) < 4 { 22 | return 0, transport.PackageLess 23 | } 24 | if len(buff) > 10485760 { 25 | return 0, transport.PackageError 26 | } 27 | var idx = bytes.Index(buff, []byte("\n")) 28 | if idx > 0 { 29 | return idx + 1, transport.PackageFull 30 | } 31 | 32 | return 0, transport.PackageLess 33 | } 34 | 35 | func getMsg(name string, idx int) []byte { 36 | arr := []string{"hello", "echo"} 37 | msg := []byte(fmt.Sprintf("cmd=%s&data=%s\n", arr[idx%2], name+strconv.Itoa(idx))) 38 | return msg 39 | } 40 | 41 | func main() { 42 | cp := &MyClient{} 43 | conf := &transport.TarsClientConf{ 44 | Proto: "tcp", 45 | QueueLen: 10000, 46 | IdleTimeout: time.Second * 5, 47 | ReadTimeout: time.Millisecond * 100, 48 | WriteTimeout: time.Millisecond * 1000, 49 | } 50 | client := transport.NewTarsClient("localhost:11028", cp, conf) 51 | 52 | name := "Bob" 53 | count := 100 54 | for i := 0; i < count; i++ { 55 | msg := getMsg(name, i) 56 | client.Send(msg) 57 | } 58 | 59 | time.Sleep(time.Second * 2) 60 | if count != cp.recvCount { 61 | fmt.Println("bad") 62 | } else { 63 | fmt.Println("good") 64 | } 65 | client.Close() 66 | } 67 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/debugtool/dumpstack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/adminf" 8 | ) 9 | 10 | func main() { 11 | comm := tars.GetCommunicator() 12 | obj := fmt.Sprintf("Test.CustomProtoServer.CustomProtoObj@tcp -h 127.0.0.1 -p 10015 -t 60000") 13 | app := new(adminf.AdminF) 14 | comm.StringToProxy(obj, app) 15 | ret, err := app.Notify("taf.dumpstack") 16 | if err != nil { 17 | fmt.Println(err) 18 | return 19 | } 20 | fmt.Println(ret) 21 | } 22 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/go.mod: -------------------------------------------------------------------------------- 1 | module CustomProtoServer 2 | 3 | go 1.14 4 | 5 | require github.com/TarsCloud/TarsGo v0.0.0 6 | 7 | replace github.com/TarsCloud/TarsGo => ../../ 8 | -------------------------------------------------------------------------------- /examples/CustomProtoServer/makefile: -------------------------------------------------------------------------------- 1 | APP := Test 2 | TARGET := CustomProtoServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk -------------------------------------------------------------------------------- /examples/CustomProtoServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./CustomProtoServer --config=CustomProtoServer.conf 4 | -------------------------------------------------------------------------------- /examples/EchoClientServer/.gitignore: -------------------------------------------------------------------------------- 1 | EchoClientServer 2 | -------------------------------------------------------------------------------- /examples/EchoClientServer/EchoClient.tars: -------------------------------------------------------------------------------- 1 | module StressTest{ 2 | interface EchoClient{ 3 | int Add(int a,int b,out int c); // Some example function 4 | int Sub(int a,int b,out int c); // Some example function 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /examples/EchoClientServer/EchoClientServer.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=StressTest 5 | server=EchoClientServer 6 | local=tcp -h 127.0.0.1 -p 11014 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 11015 -t 60000 11 | handlegroup=StressTest.EchoClientServer.EchoClientObjAdapter 12 | maxconns=200000 13 | protocol=tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=StressTest.EchoClientServer.EchoClientObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/EchoClientServer/EchoClientServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "EchoClientServer/tars-protocol/StressTest" 5 | 6 | _ "net/http/pprof" 7 | 8 | "github.com/TarsCloud/TarsGo/tars" 9 | "github.com/TarsCloud/TarsGo/tars/util/rogger" 10 | ) 11 | 12 | var app *StressTest.EchoTest 13 | var preport *tars.PropertyReport 14 | var log *rogger.Logger 15 | var remoteLog *rogger.Logger 16 | var info string 17 | var comm *tars.Communicator 18 | 19 | //EchoClientImp struct 20 | type EchoClientImp struct { 21 | } 22 | 23 | //Add implement 24 | func (imp *EchoClientImp) Add(a int32, b int32, c *int32) (int32, error) { 25 | sum := tars.NewSum() 26 | count := tars.NewCount() 27 | preport = tars.CreatePropertyReport("testproperty", sum, count) 28 | *c = a + b 29 | strIn := make([]int8, 100, 100) 30 | for i := 0; i < 100; i++ { 31 | strIn[i] = int8(i) 32 | } 33 | 34 | var strOut []int8 35 | app := new(StressTest.EchoTest) 36 | obj := "StressTest.EchoTestServer.EchoTestObj" 37 | comm.StringToProxy(obj, app) 38 | _, err := app.Echo(strIn, &strOut) 39 | if err != nil { 40 | log.Error("call error: ", err) 41 | 42 | } else { 43 | log.Debug("call succss and result[10] is ", strOut[10]) 44 | 45 | } 46 | remoteLog.Info(info) 47 | preport.Report(int(*c)) 48 | return 0, nil 49 | } 50 | 51 | //Sub implement 52 | func (imp *EchoClientImp) Sub(a int32, b int32, c *int32) (int32, error) { 53 | *c = a - b 54 | return 0, nil 55 | } 56 | 57 | func main() { //Init servant 58 | comm = tars.GetCommunicator() 59 | 60 | // client 61 | log = tars.GetDayLogger("report", 1) 62 | //config 63 | cfg := tars.GetServerConfig() 64 | remoteConf := tars.NewRConf(cfg.App, cfg.Server, cfg.BasePath) 65 | config, _ := remoteConf.GetConfig("test.conf") 66 | info = config 67 | 68 | remoteLog = tars.GetRemoteLogger("configstring") 69 | 70 | // server 71 | imp := new(EchoClientImp) //New Imp 72 | apps := new(StressTest.EchoClient) //New init the A Tars 73 | apps.AddServant(imp, cfg.App+"."+cfg.Server+".EchoClientObj") 74 | tars.Run() 75 | } 76 | -------------------------------------------------------------------------------- /examples/EchoClientServer/EchoTest.tars: -------------------------------------------------------------------------------- 1 | module StressTest{ 2 | interface EchoTest{ 3 | int echo(vector sIn, out vector sOut); 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /examples/EchoClientServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | 8 | "EchoClientServer/tars-protocol/StressTest" 9 | ) 10 | 11 | func main() { 12 | comm := tars.GetCommunicator() 13 | obj := fmt.Sprintf("StressTest.EchoClientServer.EchoClientObj@tcp -h 127.0.0.1 -p 11015 -t 60000") 14 | app := new(StressTest.EchoClient) 15 | comm.StringToProxy(obj, app) 16 | var out, i int32 17 | for i = 0; i < 100; i++ { 18 | ret, err := app.Add(i, i*2, &out) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | fmt.Println(ret, out) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/EchoClientServer/go.mod: -------------------------------------------------------------------------------- 1 | module EchoClientServer 2 | 3 | go 1.14 4 | 5 | require github.com/TarsCloud/TarsGo v0.0.0 6 | 7 | replace github.com/TarsCloud/TarsGo => ../../ 8 | -------------------------------------------------------------------------------- /examples/EchoClientServer/makefile: -------------------------------------------------------------------------------- 1 | APP := StressTest 2 | TARGET := EchoClientServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk -------------------------------------------------------------------------------- /examples/EchoClientServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./EchoClientServer --config=EchoClientServer.conf 4 | -------------------------------------------------------------------------------- /examples/EchoTestServer/.gitignore: -------------------------------------------------------------------------------- 1 | EchoTestServer 2 | -------------------------------------------------------------------------------- /examples/EchoTestServer/EchoTest.tars: -------------------------------------------------------------------------------- 1 | module StressTest{ 2 | interface EchoTest{ 3 | int echo(vector sIn, out vector sOut); 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /examples/EchoTestServer/EchoTestImp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //EchoTestImp struct 4 | type EchoTestImp struct { 5 | } 6 | 7 | //Echo implement 8 | func (imp *EchoTestImp) Echo(b []int8, c *[]int8) (int32, error) { 9 | *c = b 10 | return 0, nil 11 | } 12 | -------------------------------------------------------------------------------- /examples/EchoTestServer/EchoTestServer.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=StressTest 5 | server=EchoTestServer 6 | local=tcp -h 127.0.0.1 -p 12014 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 12015 -t 60000 11 | handlegroup=StressTest.EchoTestServer.EchoTestObjAdapter 12 | maxconns=200000 13 | protocol=tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=StressTest.EchoTestServer.EchoTestObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/EchoTestServer/EchoTestServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "path" 7 | 8 | "github.com/TarsCloud/TarsGo/tars" 9 | 10 | "EchoTestServer/tars-protocol/StressTest" 11 | "runtime/pprof" 12 | ) 13 | 14 | func main() { //Init servant 15 | cfg := tars.GetServerConfig() //Get Config File Object 16 | f, err := os.Create(path.Join(cfg.LogPath, "cpu.profile")) 17 | if err != nil { 18 | log.Fatal("could not create CPU profile: ", err) 19 | } 20 | if err := pprof.StartCPUProfile(f); err != nil { 21 | log.Fatal("could not start CPU profile: ", err) 22 | } 23 | defer pprof.StopCPUProfile() 24 | 25 | imp := new(EchoTestImp) //New Imp 26 | app := new(StressTest.EchoTest) //New init the A JCE 27 | app.AddServant(imp, cfg.App+"."+cfg.Server+".EchoTestObj") //Register Servant 28 | tars.Run() 29 | } 30 | -------------------------------------------------------------------------------- /examples/EchoTestServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | 8 | "EchoTestServer/tars-protocol/StressTest" 9 | ) 10 | 11 | func main() { 12 | comm := tars.GetCommunicator() 13 | obj := fmt.Sprintf("StressTest.EchoTestServer.EchoTestObj@tcp -h 127.0.0.1 -p 12015 -t 60000") 14 | app := new(StressTest.EchoTest) 15 | comm.StringToProxy(obj, app) 16 | var out, i []int8 17 | i = []int8{5, 2, 0} 18 | ret, err := app.Echo(i, &out) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | fmt.Println(ret, out) 24 | } 25 | -------------------------------------------------------------------------------- /examples/EchoTestServer/go.mod: -------------------------------------------------------------------------------- 1 | module EchoTestServer 2 | 3 | go 1.14 4 | 5 | require github.com/TarsCloud/TarsGo v0.0.0 6 | 7 | replace github.com/TarsCloud/TarsGo => ../../ 8 | -------------------------------------------------------------------------------- /examples/EchoTestServer/makefile: -------------------------------------------------------------------------------- 1 | APP := StressTest 2 | TARGET := EchoTestServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk -------------------------------------------------------------------------------- /examples/EchoTestServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./EchoTestServer --config=EchoTestServer.conf 4 | -------------------------------------------------------------------------------- /examples/GinHttpServer/config.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=Gin 5 | server=HttpServer 6 | local=tcp -h 127.0.0.1 -p 13014 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 8088 -t 60000 11 | handlegroup=Gin.HttpServer.HttpObjAdapter 12 | maxconns=200000 13 | protocol=no_tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=Gin.HttpServer.HttpObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/GinHttpServer/go.mod: -------------------------------------------------------------------------------- 1 | module gin 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.3 7 | github.com/TarsCloud/TarsGo/contrib/gin v0.0.1-bate3 8 | github.com/gin-gonic/gin v1.9.1 9 | ) 10 | 11 | require ( 12 | github.com/bytedance/sonic v1.9.1 // indirect 13 | github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect 14 | github.com/gabriel-vasile/mimetype v1.4.2 // indirect 15 | github.com/gin-contrib/sse v0.1.0 // indirect 16 | github.com/go-playground/locales v0.14.1 // indirect 17 | github.com/go-playground/universal-translator v0.18.1 // indirect 18 | github.com/go-playground/validator/v10 v10.14.0 // indirect 19 | github.com/goccy/go-json v0.10.2 // indirect 20 | github.com/json-iterator/go v1.1.12 // indirect 21 | github.com/klauspost/cpuid/v2 v2.2.4 // indirect 22 | github.com/leodido/go-urn v1.2.4 // indirect 23 | github.com/mattn/go-isatty v0.0.19 // indirect 24 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 25 | github.com/modern-go/reflect2 v1.0.2 // indirect 26 | github.com/pelletier/go-toml/v2 v2.0.8 // indirect 27 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 28 | github.com/ugorji/go/codec v1.2.11 // indirect 29 | go.uber.org/automaxprocs v1.5.2 // indirect 30 | golang.org/x/arch v0.3.0 // indirect 31 | golang.org/x/crypto v0.9.0 // indirect 32 | golang.org/x/net v0.10.0 // indirect 33 | golang.org/x/sys v0.8.0 // indirect 34 | golang.org/x/text v0.9.0 // indirect 35 | google.golang.org/protobuf v1.30.0 // indirect 36 | gopkg.in/yaml.v3 v3.0.1 // indirect 37 | ) 38 | 39 | replace github.com/TarsCloud/TarsGo => ../../ 40 | -------------------------------------------------------------------------------- /examples/GinHttpServer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | cgin "github.com/TarsCloud/TarsGo/contrib/gin" 5 | "github.com/TarsCloud/TarsGo/tars" 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | func main() { 10 | g := cgin.New() 11 | g.GET("/ping", func(c *gin.Context) { 12 | c.JSON(200, gin.H{ 13 | "message": "pong", 14 | }) 15 | }) 16 | 17 | // Get server config 18 | cfg := tars.GetServerConfig() 19 | tars.AddHttpServant(g, cfg.App+"."+cfg.Server+".HttpObj") 20 | tars.Run() 21 | } 22 | -------------------------------------------------------------------------------- /examples/GinHttpServer/makefile: -------------------------------------------------------------------------------- 1 | APP := Gin 2 | TARGET := HttpServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk -------------------------------------------------------------------------------- /examples/GinHttpServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./HttpServer --config=config.conf 4 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/.gitignore: -------------------------------------------------------------------------------- 1 | OpentelemetryServer 2 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/Opentelemetry.tars: -------------------------------------------------------------------------------- 1 | module StressTest { 2 | interface Opentelemetry { 3 | int Add(int a,int b,out int c); // Some example function 4 | int Sub(int a,int b,out int c); // Some example function 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/OpentelemetryImp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "go.opentelemetry.io/otel" 7 | "go.opentelemetry.io/otel/attribute" 8 | "go.opentelemetry.io/otel/trace" 9 | 10 | "github.com/TarsCloud/TarsGo/tars" 11 | "github.com/TarsCloud/TarsGo/tars/util/current" 12 | ) 13 | 14 | var name = "OpentelemetryImp" 15 | 16 | type OpentelemetryImp struct { 17 | } 18 | 19 | func (imp *OpentelemetryImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 20 | span := trace.SpanContextFromContext(ctx) 21 | logger := tars.GetLogger("context") 22 | data, err := span.MarshalJSON() 23 | if err != nil { 24 | logger.Errorf("MarshalJSON err:%v", err) 25 | } 26 | logger.Info("span", string(data)) 27 | ip, ok := current.GetClientIPFromContext(ctx) 28 | if !ok { 29 | logger.Error("Error getting ip from context") 30 | } 31 | logger.Infof("Get Client Ip : %s from context", ip) 32 | reqContext, ok := current.GetRequestContext(ctx) 33 | if !ok { 34 | logger.Error("Error getting reqcontext from context") 35 | } 36 | logger.Infof("Get context from context: %v", reqContext) 37 | k := make(map[string]string) 38 | k["resp"] = "respform context" 39 | ok = current.SetResponseContext(ctx, k) 40 | if !ok { 41 | logger.Error("error setting respose context") 42 | } 43 | imp.Sub(ctx, a, b, c) 44 | //Doing something in your function 45 | //... 46 | *c = a * b 47 | return 0, nil 48 | } 49 | 50 | func (imp *OpentelemetryImp) Sub(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 51 | _, span := otel.Tracer(name).Start(ctx, "Sub") 52 | defer span.End() 53 | span.SetAttributes(attribute.Int64("request.a", int64(a))) 54 | span.SetAttributes(attribute.Int64("request.b", int64(b))) 55 | //... 56 | return 0, nil 57 | } 58 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/OpentelemetryServer.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=StressTest 5 | server=OpentelemetryServer 6 | local=tcp -h 127.0.0.1 -p 10027 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 10028 -t 60000 11 | handlegroup=StressTest.OpentelemetryServer.OpenTelemetryObjAdapter 12 | maxconns=200000 13 | protocol=tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=StressTest.OpentelemetryServer.OpenTelemetryObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/OpentelemetryServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | 8 | "OpentelemetryServer/otel" 9 | "OpentelemetryServer/tars-protocol/StressTest" 10 | 11 | "github.com/TarsCloud/TarsGo/contrib/middleware/opentelemetry" 12 | "github.com/TarsCloud/TarsGo/tars" 13 | ) 14 | 15 | func main() { 16 | cfg := tars.GetServerConfig() 17 | serviceNameKey := fmt.Sprintf("%s.%s", cfg.App, cfg.Server) 18 | tp := otel.NewTracerProvider(serviceNameKey, "") 19 | mp := otel.NewMeterProvider(serviceNameKey, "") 20 | defer func() { 21 | if err := mp.Shutdown(context.Background()); err != nil { 22 | log.Printf("Error shutting down metrics provider: %v", err) 23 | } 24 | 25 | if err := tp.Shutdown(context.Background()); err != nil { 26 | log.Printf("Error shutting down traces provider: %v", err) 27 | } 28 | }() 29 | 30 | filter := opentelemetry.New() 31 | tars.UseServerFilterMiddleware(filter.BuildServerFilter()) 32 | tars.UseClientFilterMiddleware(filter.BuildClientFilter()) 33 | imp := new(OpentelemetryImp) //New Imp 34 | app := new(StressTest.Opentelemetry) //New init the A Tars 35 | app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".OpenTelemetryObj") //Register Servant 36 | tars.Run() 37 | } 38 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "time" 8 | 9 | "OpentelemetryServer/otel" 10 | "OpentelemetryServer/tars-protocol/StressTest" 11 | 12 | "github.com/TarsCloud/TarsGo/contrib/middleware/opentelemetry" 13 | "github.com/TarsCloud/TarsGo/tars" 14 | "github.com/TarsCloud/TarsGo/tars/util/current" 15 | ) 16 | 17 | func main() { 18 | serviceNameKey := fmt.Sprintf("%s.%s", "StressTest", "OpentelemetryClient") 19 | tp := otel.NewTracerProvider(serviceNameKey, "") 20 | defer func() { 21 | if err := tp.Shutdown(context.Background()); err != nil { 22 | log.Printf("Error shutting down tracer provider: %v", err) 23 | } 24 | }() 25 | filter := opentelemetry.New() 26 | tars.UseClientFilterMiddleware(filter.BuildClientFilter()) 27 | comm := tars.GetCommunicator() 28 | obj := fmt.Sprintf("StressTest.OpentelemetryServer.OpenTelemetryObj@tcp -h 127.0.0.1 -p 10028 -t 60000") 29 | app := new(StressTest.Opentelemetry) 30 | comm.StringToProxy(obj, app) 31 | var out, i int32 32 | i = 11111 33 | ctx := current.ContextWithClientCurrent(context.Background()) 34 | c := make(map[string]string) 35 | c["a"] = "b" 36 | for { 37 | ret, err := app.AddWithContext(ctx, i, i*2, &out, c) 38 | if err != nil { 39 | fmt.Printf("error: %v", err) 40 | return 41 | } 42 | fmt.Println(c) 43 | fmt.Println(ret, out) 44 | 45 | ret, err = app.SubWithContext(ctx, i, i*2, &out, c) 46 | if err != nil { 47 | fmt.Printf("error: %v", err) 48 | return 49 | } 50 | fmt.Println(c) 51 | fmt.Println(ret, out) 52 | time.Sleep(time.Second * 5) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/debugtool/dumpstack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/adminf" 8 | ) 9 | 10 | func main() { 11 | comm := tars.GetCommunicator() 12 | obj := fmt.Sprintf("StressTest.OpentelemetryServer.OpentelemetryObj@tcp -h 127.0.0.1 -p 10014 -t 60000") 13 | app := new(adminf.AdminF) 14 | comm.StringToProxy(obj, app) 15 | ret, err := app.Notify("tars.dumpstack") 16 | if err != nil { 17 | fmt.Println(err) 18 | return 19 | } 20 | fmt.Println(ret) 21 | } 22 | -------------------------------------------------------------------------------- /examples/OpentelemetryServer/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | # Jaeger 3 | jaeger-all-in-one: 4 | image: jaegertracing/all-in-one:latest 5 | ports: 6 | - "16686:16686" 7 | - "14268:14268" 8 | - "14250:14250" 9 | 10 | # Zipkin 11 | zipkin-all-in-one: 12 | image: openzipkin/zipkin:latest 13 | ports: 14 | - "19411:9411" 15 | 16 | prometheus: 17 | image: prom/prometheus:latest 18 | volumes: 19 | - ./prometheus.yaml:/etc/prometheus/prometheus.yml 20 | ports: 21 | - "9090:9090" 22 | 23 | otel-collector: 24 | image: otel/opentelemetry-collector:0.55.0 25 | command: [ "--config=/etc/otel-collector-config.yaml" ] 26 | volumes: 27 | - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml 28 | ports: 29 | - "1888:1888" # pprof 扩展端口 30 | - "8888:8888" # otel 暴露的 Prometheus 端口 31 | - "8889:8889" # Prometheus exporter 端口 32 | - "13133:13133" # 健康检查扩展 33 | - "4317:4317" # OTLP gRPC 接收器端口 34 | - "4318:4318" # OTLP http 接收器端口 35 | - "55679:55679" # zpages 扩展端口 36 | depends_on: 37 | - jaeger-all-in-one 38 | - zipkin-all-in-one -------------------------------------------------------------------------------- /examples/OpentelemetryServer/makefile: -------------------------------------------------------------------------------- 1 | APP := StressTest 2 | TARGET := OpentelemetryServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk -------------------------------------------------------------------------------- /examples/OpentelemetryServer/otel-collector-config.yaml: -------------------------------------------------------------------------------- 1 | receivers: 2 | otlp: 3 | protocols: 4 | grpc: 5 | 6 | exporters: 7 | prometheus: 8 | endpoint: "0.0.0.0:8889" 9 | const_labels: 10 | label1: value1 11 | 12 | logging: 13 | 14 | zipkin: 15 | endpoint: "http://zipkin-all-in-one:19411/api/v2/spans" 16 | format: proto 17 | 18 | jaeger: 19 | endpoint: jaeger-all-in-one:14250 20 | tls: 21 | insecure: true 22 | 23 | processors: 24 | batch: 25 | 26 | extensions: 27 | health_check: 28 | pprof: 29 | endpoint: :1888 30 | zpages: 31 | endpoint: :55679 32 | 33 | service: 34 | extensions: [pprof, zpages, health_check] 35 | pipelines: 36 | traces: 37 | receivers: [otlp] 38 | processors: [batch] 39 | exporters: [logging, jaeger] 40 | metrics: 41 | receivers: [otlp] 42 | processors: [batch] 43 | exporters: [logging, prometheus] -------------------------------------------------------------------------------- /examples/OpentelemetryServer/prometheus.yaml: -------------------------------------------------------------------------------- 1 | scrape_configs: 2 | - job_name: 'otel-collector' 3 | scrape_interval: 10s 4 | static_configs: 5 | - targets: ['otel-collector:8889'] 6 | - targets: ['otel-collector:8888'] 7 | - job_name: 'observability-example' 8 | scrape_interval: 10s 9 | static_configs: 10 | - targets: [ 'host.docker.internal:18081' ] -------------------------------------------------------------------------------- /examples/OpentelemetryServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./OpentelemetryServer --config=OpentelemetryServer.conf 4 | -------------------------------------------------------------------------------- /examples/PushServer/.gitignore: -------------------------------------------------------------------------------- 1 | PushServer 2 | -------------------------------------------------------------------------------- /examples/PushServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/TarsCloud/TarsGo/tars" 8 | "github.com/TarsCloud/TarsGo/tars/protocol/push" 9 | ) 10 | 11 | func callback(data []byte) { 12 | fmt.Println("recv message:", string(data)) 13 | } 14 | 15 | func main() { 16 | comm := tars.GetCommunicator() 17 | obj := "TestApp.PushServer.MessageObj@tcp -h 127.0.0.1 -p 10015 -t 60000" 18 | client := push.NewClient(callback) 19 | comm.StringToProxy(obj, client) 20 | data, err := client.Connect([]byte("hello")) 21 | if err != nil { 22 | panic(err) 23 | } 24 | fmt.Println("connect ok", string(data)) 25 | // Wait for receving message 26 | time.Sleep(time.Second * 10) 27 | } 28 | -------------------------------------------------------------------------------- /examples/PushServer/config.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=TestApp 5 | server=PushServer 6 | local=tcp -h 127.0.0.1 -p 10014 -t 30000 7 | logpath=/tmp 8 | 9 | allow 10 | endpoint=tcp -h 127.0.0.1 -p 10015 -t 60000 11 | handlegroup=TestApp.PushServer.MessageObjAdapter 12 | maxconns=200000 13 | protocol=not_tars 14 | queuecap=10000 15 | queuetimeout=60000 16 | servant=TestApp.PushServer.MessageObj 17 | shmcap=0 18 | shmkey=0 19 | threads=1 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/PushServer/debugtool/dumpstack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/adminf" 8 | ) 9 | 10 | func main() { 11 | comm := tars.GetCommunicator() 12 | obj := "TestApp.PushServer.MessageObj@tcp -h 127.0.0.1 -p 10014 -t 60000" 13 | app := new(adminf.AdminF) 14 | comm.StringToProxy(obj, app) 15 | ret, err := app.Notify("tars.dumpstack") 16 | if err != nil { 17 | fmt.Println(err) 18 | return 19 | } 20 | fmt.Println(ret) 21 | } 22 | -------------------------------------------------------------------------------- /examples/PushServer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/TarsCloud/TarsGo/tars" 9 | "github.com/TarsCloud/TarsGo/tars/protocol/push" 10 | "github.com/TarsCloud/TarsGo/tars/util/current" 11 | ) 12 | 13 | type pushImp struct{} 14 | 15 | // OnConnect ... 16 | func (p *pushImp) OnConnect(ctx context.Context, req []byte) []byte { 17 | ip, _ := current.GetClientIPFromContext(ctx) 18 | port, _ := current.GetClientPortFromContext(ctx) 19 | fmt.Println("on connect:", ip, port) 20 | go func() { 21 | for i := 0; i < 3; i++ { 22 | time.Sleep(time.Millisecond * 100) 23 | if err := push.Send(ctx, []byte("msg"+fmt.Sprint(i))); err != nil { 24 | fmt.Println("send error", err) 25 | } 26 | } 27 | }() 28 | return req 29 | } 30 | 31 | // OnClose ... 32 | func (p *pushImp) OnClose(ctx context.Context) { 33 | ip, _ := current.GetClientIPFromContext(ctx) 34 | port, _ := current.GetClientPortFromContext(ctx) 35 | fmt.Println("on close:", ip, port) 36 | } 37 | 38 | func main() { 39 | cfg := tars.GetServerConfig() 40 | proto := push.NewServer(&pushImp{}) 41 | tars.AddServantWithProtocol(proto, cfg.App+"."+cfg.Server+".MessageObj") 42 | tars.Run() 43 | } 44 | -------------------------------------------------------------------------------- /examples/PushServer/makefile: -------------------------------------------------------------------------------- 1 | APP := TestApp 2 | TARGET := PushServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk 10 | -------------------------------------------------------------------------------- /examples/PushServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | make 4 | ./PushServer --config=config.conf 5 | -------------------------------------------------------------------------------- /examples/Tars2Go/README.md: -------------------------------------------------------------------------------- 1 | # 支持include参数 和 单个tars协议文件定义多个module 2 | ```bash 3 | cd ../../tars/tools/tars2go && go install && cd - 4 | tars2go -include=base -outdir=tars-protocol -module demo demo.tars 5 | # 或者 6 | go run ../../tars/tools/tars2go/*.go -include=base -outdir=tars-protocol -module demo demo.tars 7 | ``` -------------------------------------------------------------------------------- /examples/Tars2Go/base/demo1.tars: -------------------------------------------------------------------------------- 1 | module Base 2 | { 3 | enum Code 4 | { 5 | Success = 0, 6 | Error = 1 7 | }; 8 | }; -------------------------------------------------------------------------------- /examples/Tars2Go/demo.tars: -------------------------------------------------------------------------------- 1 | #include "demo1.tars" 2 | module DemoV1 3 | { 4 | struct DemoV1 5 | { 6 | 0 optional string ip; 7 | }; 8 | }; 9 | module DemoV2 10 | { 11 | struct DemoRoom 12 | { 13 | 0 optional long id; 14 | }; 15 | }; 16 | module DemoV1 17 | { 18 | struct DemoV11 19 | { 20 | 1 optional long id; 21 | }; 22 | }; 23 | 24 | module DemoV3 25 | { 26 | interface V3Test{ 27 | int echo(DemoV1::DemoV1 sIn, out DemoV1::DemoV11 sOut); 28 | }; 29 | }; -------------------------------------------------------------------------------- /examples/Tars2Go/go.mod: -------------------------------------------------------------------------------- 1 | module demo 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.0 7 | github.com/golang/protobuf v1.5.3 8 | google.golang.org/protobuf v1.30.0 9 | ) 10 | -------------------------------------------------------------------------------- /examples/TlsTestServer/.gitignore: -------------------------------------------------------------------------------- 1 | TlsTestServer 2 | ssl 3 | tars-protocol -------------------------------------------------------------------------------- /examples/TlsTestServer/Tls.tars: -------------------------------------------------------------------------------- 1 | module App 2 | { 3 | interface Tls 4 | { 5 | int Add(int a,int b,out int c); // Some example function 6 | int Sub(int a,int b,out int c); // Some example function 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /examples/TlsTestServer/Tls_imp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | // TlsImp servant implementation 8 | type TlsImp struct { 9 | } 10 | 11 | // Init servant init 12 | func (imp *TlsImp) Init() error { 13 | //initialize servant here: 14 | //... 15 | return nil 16 | } 17 | 18 | // Destroy servant destory 19 | func (imp *TlsImp) Destroy() { 20 | //destroy servant here: 21 | //... 22 | } 23 | 24 | func (imp *TlsImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 25 | //Doing something in your function 26 | //... 27 | return 0, nil 28 | } 29 | func (imp *TlsImp) Sub(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 30 | //Doing something in your function 31 | //... 32 | return 0, nil 33 | } 34 | -------------------------------------------------------------------------------- /examples/TlsTestServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | 8 | "TlsTestServer/tars-protocol/App" 9 | ) 10 | 11 | func main() { 12 | tars.ServerConfigPath = "config.conf" 13 | comm := tars.GetCommunicator() 14 | obj := fmt.Sprintf("App.TlsTestServer.TlsObj@ssl -h 127.0.0.1 -p 13015 -t 6000000000") 15 | app := new(App.Tls) 16 | comm.StringToProxy(obj, app) 17 | var out, i int32 18 | i = 123 19 | ret, err := app.Add(i, i*2, &out) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | fmt.Println(ret, out) 25 | } 26 | -------------------------------------------------------------------------------- /examples/TlsTestServer/config.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # ca证书 5 | ca=ssl/ca.crt 6 | # 客户端public证书 7 | cert=ssl/client.crt 8 | # 客户端私钥 9 | key=ssl/client.key 10 | 11 | ca=ssl/ca.crt 12 | # 客户端public证书 13 | cert=ssl/client.crt 14 | # 客户端私钥 15 | key=ssl/client.key 16 | 17 | 18 | 19 | app=App 20 | server=TlsTestServer 21 | local=tcp -h 127.0.0.1 -p 13014 -t 30000 22 | logpath=/tmp 23 | # ca公有证书,不验证客户端可以不填写 24 | ca=ssl/ca.crt 25 | # 不验证客户端 26 | verifyclient=1 27 | # 服务器public证书 28 | cert=ssl/server.crt 29 | # 服务器private证书 30 | key=ssl/server.key 31 | 32 | allow 33 | endpoint=ssl -h 127.0.0.1 -p 13015 -t 60000 34 | handlegroup=App.TlsTestServer.TlsObjAdapter 35 | maxconns=200000 36 | protocol=tars 37 | queuecap=10000 38 | queuetimeout=60000 39 | servant=App.TlsTestServer.TlsObj 40 | shmcap=0 41 | shmkey=0 42 | threads=1 43 | 44 | 45 | allow 46 | endpoint=ssl -h 127.0.0.1 -p 4443 -t 60000 47 | handlegroup=App.TlsTestServer.HttpsObjAdapter 48 | maxconns=200000 49 | protocol=tars 50 | queuecap=10000 51 | queuetimeout=60000 52 | servant=App.TlsTestServer.HttpsObj 53 | shmcap=0 54 | shmkey=0 55 | threads=1 56 | # ca公有证书,不验证客户端可以不填写 57 | ca=ssl/ca.crt 58 | # 不验证客户端 59 | verifyclient=0 60 | # 服务器public证书 61 | cert=ssl/server.crt 62 | # 服务器private证书 63 | key=ssl/server.key 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/TlsTestServer/debugtool/dumpstack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/adminf" 8 | ) 9 | 10 | func main() { 11 | comm := tars.GetCommunicator() 12 | obj := fmt.Sprintf("App.TlsTestServer.TlsObj@tcp -h 127.0.0.1 -p 10014 -t 60000") 13 | app := new(adminf.AdminF) 14 | comm.StringToProxy(obj, app) 15 | ret, err := app.Notify("tars.dumpstack") 16 | if err != nil { 17 | fmt.Println(err) 18 | return 19 | } 20 | fmt.Println(ret) 21 | } 22 | -------------------------------------------------------------------------------- /examples/TlsTestServer/go.mod: -------------------------------------------------------------------------------- 1 | module TlsTestServer 2 | 3 | go 1.14 4 | 5 | require github.com/TarsCloud/TarsGo v0.0.0 6 | 7 | replace github.com/TarsCloud/TarsGo => ../../ 8 | -------------------------------------------------------------------------------- /examples/TlsTestServer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | "time" 8 | 9 | "github.com/TarsCloud/TarsGo/tars" 10 | 11 | "TlsTestServer/tars-protocol/App" 12 | ) 13 | 14 | func main() { 15 | // Get server config 16 | cfg := tars.GetServerConfig() 17 | 18 | // New servant imp 19 | imp := new(TlsImp) 20 | err := imp.Init() 21 | if err != nil { 22 | fmt.Printf("TlsImp init fail, err:(%s)\n", err) 23 | os.Exit(-1) 24 | } 25 | // New servant 26 | app := new(App.Tls) 27 | // Register Servant 28 | app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".TlsObj") 29 | mux := &tars.TarsHttpMux{} 30 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 31 | w.Write([]byte(fmt.Sprintf("%d", time.Now().UnixNano()/1e6))) 32 | }) 33 | //Register http server 34 | tars.AddHttpServant(mux, cfg.App+"."+cfg.Server+".HttpsObj") 35 | 36 | // Run application 37 | tars.Run() 38 | } 39 | -------------------------------------------------------------------------------- /examples/TlsTestServer/makefile: -------------------------------------------------------------------------------- 1 | APP := App 2 | TARGET := TlsTestServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include scripts/makefile.tars.gomod.mk 10 | -------------------------------------------------------------------------------- /examples/TlsTestServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | make 4 | ./TlsTestServer --config=config.conf 5 | -------------------------------------------------------------------------------- /examples/TlsTestServer/tls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 参考文档 3 | # https://www.mingfer.cn/2020/06/13/altern-name/ 4 | # https://www.jianshu.com/p/ea5bc56211ee 5 | # https://github.com/square/certstrap 6 | # https://github.com/cloudflare/cfssl 7 | # https://stackoverflow.com/questions/54622879/cannot-validate-certificate-for-ip-address-because-it-doesnt-contain-any-ip-s 8 | # https://security.stackexchange.com/questions/74345/provide-subjectaltname-to-openssl-directly-on-the-command-line/183973#183973 9 | # https://blog.csdn.net/u012094456/article/details/101352543 10 | set -ex 11 | mkdir -p ssl 12 | cd ssl 13 | # ca 14 | openssl genrsa -out ca.key 2048 15 | openssl req -x509 -new -nodes -key ca.key -days 1024 -out ca.crt \ 16 | -subj "/C=CN/ST=BeiJing/L=BJ/O=Tars/OU=TarsGo/CN=TarsCa/emailAddress=tarsgo@tarscloud.com" 17 | 18 | # server 19 | openssl genrsa -out server.key 2048 20 | openssl req -new -key server.key -out server.csr \ 21 | -subj "/C=CN/ST=BeiJing/L=BJ/O=Tars/OU=TarsGo/CN=server/emailAddress=tarsgo@tarscloud.com"\ 22 | -addext "subjectAltName=IP:127.0.0.1" 23 | #openssl req -text -in server.csr -noout -verify 24 | openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 500 \ 25 | -extfile <(printf "subjectAltName=IP:127.0.0.1") 26 | #openssl x509 -in server.crt -noout -text 27 | 28 | # client 29 | openssl genrsa -out client.key 2048 30 | openssl req -new -key client.key -out client.csr \ 31 | -subj "/C=CN/ST=BeiJing/L=BJ/O=Tars/OU=TarsGo/CN=client/emailAddress=tarsgo@tarscloud.com" 32 | #openssl req -text -in client.csr -noout -verify 33 | openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 500 34 | cd - 35 | -------------------------------------------------------------------------------- /examples/trace/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | logs 4 | tars-protocol 5 | TarsTraceBackServer/TarsTraceBackServer 6 | TarsTraceFrontServer/TarsTraceFrontServer 7 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/Backend.tars: -------------------------------------------------------------------------------- 1 | module Trace 2 | { 3 | interface Backend 4 | { 5 | int Add(int a,int b,out int c); // Some example function 6 | int Sub(int a,int b,out int c); // Some example function 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/Backend_imp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | // BackendImp servant implementation 8 | type BackendImp struct { 9 | } 10 | 11 | // Init servant init 12 | func (imp *BackendImp) Init() error { 13 | //initialize servant here: 14 | //... 15 | return nil 16 | } 17 | 18 | // Destroy servant destory 19 | func (imp *BackendImp) Destroy() { 20 | //destroy servant here: 21 | //... 22 | } 23 | 24 | func (imp *BackendImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 25 | //Doing something in your function 26 | *c = a + b 27 | return 0, nil 28 | } 29 | func (imp *BackendImp) Sub(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 30 | //Doing something in your function 31 | *c = a - b 32 | return 0, nil 33 | } 34 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | 8 | "trace/backend/tars-protocol/Trace" 9 | ) 10 | 11 | func main() { 12 | comm := tars.GetCommunicator() 13 | obj := fmt.Sprintf("Trace.TarsTraceBackServer.BackendObj@tcp -h 127.0.0.1 -p 20015 -t 60000") 14 | app := new(Trace.Backend) 15 | comm.StringToProxy(obj, app) 16 | var out, i int32 17 | i = 123 18 | ret, err := app.Add(i, i*2, &out) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | fmt.Println(ret, out) 24 | } 25 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/config.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | modulename=Trace.TarsTraceBackServer 5 | property=tars.tarsproperty.PropertyObj@tcp -h 127.0.0.1 -t 60000 -p 18493 6 | 7 | 8 | app=Trace 9 | server=TarsTraceBackServer 10 | local=tcp -h 127.0.0.1 -p 20014 -t 30000 11 | logpath=logs 12 | log=tars.tarslog.LogObj@tcp -h 127.0.0.1 -t 60000 -p 18993 13 | 14 | allow 15 | endpoint=tcp -h 127.0.0.1 -p 20015 -t 60000 16 | handlegroup=Trace.TarsTraceBackServer.BackendObjAdapter 17 | maxconns=200000 18 | protocol=tars 19 | queuecap=10000 20 | queuetimeout=60000 21 | servant=Trace.TarsTraceBackServer.BackendObj 22 | shmcap=0 23 | shmkey=0 24 | threads=1 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/debugtool/dumpstack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/adminf" 8 | ) 9 | 10 | func main() { 11 | comm := tars.GetCommunicator() 12 | obj := fmt.Sprintf("Trace.TarsTraceBackServer.BackendObj@tcp -h 127.0.0.1 -p 10014 -t 60000") 13 | app := new(adminf.AdminF) 14 | comm.StringToProxy(obj, app) 15 | ret, err := app.Notify("tars.dumpstack") 16 | if err != nil { 17 | fmt.Println(err) 18 | return 19 | } 20 | fmt.Println(ret) 21 | } 22 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/go.mod: -------------------------------------------------------------------------------- 1 | module trace/backend 2 | 3 | go 1.16 4 | 5 | require github.com/TarsCloud/TarsGo v1.2.0 6 | 7 | replace github.com/TarsCloud/TarsGo v1.2.0 => ../../../ 8 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/TarsCloud/TarsGo/tars" 8 | 9 | "trace/backend/tars-protocol/Trace" 10 | ) 11 | 12 | func main() { 13 | // Get server config 14 | cfg := tars.GetServerConfig() 15 | 16 | // New servant imp 17 | imp := new(BackendImp) 18 | err := imp.Init() 19 | if err != nil { 20 | fmt.Printf("BackendImp init fail, err:(%s)\n", err) 21 | os.Exit(-1) 22 | } 23 | // New servant 24 | app := new(Trace.Backend) 25 | // Register Servant 26 | app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".BackendObj") 27 | 28 | // Run application 29 | tars.Run() 30 | } 31 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/makefile: -------------------------------------------------------------------------------- 1 | APP := Trace 2 | TARGET := TarsTraceBackServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include scripts/makefile.tars.gomod.mk 10 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceBackServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | make 4 | ./TarsTraceBackServer --config=config.conf 5 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/Frontend.tars: -------------------------------------------------------------------------------- 1 | module Trace 2 | { 3 | interface Frontend 4 | { 5 | int Add(int a,int b,out int c); // Some example function 6 | int Sub(int a,int b,out int c); // Some example function 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/Frontend_imp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "trace/backend/tars-protocol/Trace" 8 | ) 9 | 10 | // FrontendImp servant implementation 11 | type FrontendImp struct { 12 | backend *Trace.Backend 13 | } 14 | 15 | // Init servant init 16 | func (imp *FrontendImp) Init() error { 17 | //initialize servant here: 18 | comm := tars.GetCommunicator() 19 | obj := fmt.Sprintf("Trace.TarsTraceBackServer.BackendObj@tcp -h 127.0.0.1 -p 20015 -t 60000") 20 | app := new(Trace.Backend) 21 | comm.StringToProxy(obj, app) 22 | imp.backend = app 23 | return nil 24 | } 25 | 26 | // Destroy servant destory 27 | func (imp *FrontendImp) Destroy() { 28 | //destroy servant here: 29 | //... 30 | } 31 | 32 | func (imp *FrontendImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 33 | //Doing something in your function 34 | return imp.backend.AddWithContext(ctx, a, b, c) 35 | } 36 | func (imp *FrontendImp) Sub(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 37 | //Doing something in your function 38 | return imp.backend.SubWithContext(ctx, a, b, c) 39 | } 40 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "github.com/TarsCloud/TarsGo/tars/util/current" 8 | 9 | "trace/frontend/tars-protocol/Trace" 10 | ) 11 | 12 | func main() { 13 | tars.ServerConfigPath = "config.conf" 14 | comm := tars.GetCommunicator() 15 | obj := fmt.Sprintf("Trace.TarsTraceFrontServer.FrontendObj@tcp -h 127.0.0.1 -p 10015 -t 60000") 16 | app := new(Trace.Frontend) 17 | comm.StringToProxy(obj, app) 18 | var out, i int32 19 | i = 123 20 | ctx := current.ContextWithTarsCurrent(context.Background()) 21 | current.OpenTarsTrace(ctx, true) 22 | ret, err := app.AddWithContext(ctx, i, i*2, &out) 23 | if err != nil { 24 | fmt.Println(err) 25 | return 26 | } 27 | fmt.Println(ret, out) 28 | } 29 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/config.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | modulename=Trace.TarsTraceFrontServer 5 | property=tars.tarsproperty.PropertyObj@tcp -h 127.0.0.1 -t 60000 -p 18493 6 | 7 | 8 | app=Trace 9 | server=TarsTraceFrontServer 10 | local=tcp -h 127.0.0.1 -p 10014 -t 30000 11 | logpath=/tmp 12 | log=tars.tarslog.LogObj@tcp -h 127.0.0.1 -t 60000 -p 18993 13 | 14 | allow 15 | endpoint=tcp -h 127.0.0.1 -p 10015 -t 60000 16 | handlegroup=Trace.TarsTraceFrontServer.FrontendObjAdapter 17 | maxconns=200000 18 | protocol=tars 19 | queuecap=10000 20 | queuetimeout=60000 21 | servant=Trace.TarsTraceFrontServer.FrontendObj 22 | shmcap=0 23 | shmkey=0 24 | threads=1 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/debugtool/dumpstack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/adminf" 8 | ) 9 | 10 | func main() { 11 | comm := tars.GetCommunicator() 12 | obj := fmt.Sprintf("Trace.TarsTraceFrontServer.FrontendObj@tcp -h 127.0.0.1 -p 10014 -t 60000") 13 | app := new(adminf.AdminF) 14 | comm.StringToProxy(obj, app) 15 | ret, err := app.Notify("tars.dumpstack") 16 | if err != nil { 17 | fmt.Println(err) 18 | return 19 | } 20 | fmt.Println(ret) 21 | } 22 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/go.mod: -------------------------------------------------------------------------------- 1 | module trace/frontend 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.2.0 7 | trace/backend v0.0.0-00010101000000-000000000000 8 | ) 9 | 10 | replace ( 11 | github.com/TarsCloud/TarsGo v1.2.0 => ../../../ 12 | trace/backend => ../TarsTraceBackServer 13 | ) 14 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/TarsCloud/TarsGo/tars" 8 | 9 | "trace/frontend/tars-protocol/Trace" 10 | ) 11 | 12 | func main() { 13 | // Get server config 14 | cfg := tars.GetServerConfig() 15 | 16 | // New servant imp 17 | imp := new(FrontendImp) 18 | err := imp.Init() 19 | if err != nil { 20 | fmt.Printf("FrontendImp init fail, err:(%s)\n", err) 21 | os.Exit(-1) 22 | } 23 | // New servant 24 | app := new(Trace.Frontend) 25 | // Register Servant 26 | app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".FrontendObj") 27 | 28 | // Run application 29 | tars.Run() 30 | } 31 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/makefile: -------------------------------------------------------------------------------- 1 | APP := Trace 2 | TARGET := TarsTraceFrontServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include scripts/makefile.tars.gomod.mk 10 | -------------------------------------------------------------------------------- /examples/trace/TarsTraceFrontServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | make 4 | ./TarsTraceFrontServer --config=config.conf 5 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/.gitignore: -------------------------------------------------------------------------------- 1 | ZipkinTraceClient 2 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/ZipkinClient.tars: -------------------------------------------------------------------------------- 1 | module ZipkinTraceApp 2 | { 3 | interface ZipkinClient 4 | { 5 | int Add(int a, int b, out int c); // Some example function 6 | int Sub(int a, int b, out int c); // Some example function 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/ZipkinClientImp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "context" 4 | 5 | // ZipkinClientImp struct 6 | type ZipkinClientImp struct { 7 | } 8 | 9 | // Add implemnet 10 | func (imp *ZipkinClientImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 11 | //Doing something in your function 12 | //... 13 | *c = a * b 14 | var d int32 15 | _, err := sapp.AddWithContext(ctx, *c, *c, &d) 16 | if err != nil { 17 | logger.Error("Error call add ", err) 18 | } 19 | 20 | return 0, nil 21 | } 22 | 23 | // Sub implement 24 | func (imp *ZipkinClientImp) Sub(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 25 | //Doing something in your function 26 | //... 27 | return 0, nil 28 | } 29 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/ZipkinTrace.tars: -------------------------------------------------------------------------------- 1 | module ZipkinTraceApp{ 2 | interface ZipkinTrace{ 3 | 4 | int Add(int a,int b,out int c); // Some example function 5 | int Sub(int a,int b,out int c); // Some example function 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/ZipkinTraceClient.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=ZipkinTraceApp 5 | server=ZipkinTraceClient 6 | local=tcp -h 127.0.0.1 -p 14014 -t 30000 7 | logpath=/tmp 8 | samplerate=0.5 9 | sampleaddress=http://127.0.0.1:9411 10 | sampletype=http 11 | sampleencoding=json 12 | 13 | allow 14 | endpoint=tcp -h 127.0.0.1 -p 14015 -t 60000 15 | handlegroup=ZipkinTraceApp.ZipkinTraceClient.ZipkinClientObjAdapter 16 | maxconns=200000 17 | protocol=tars 18 | queuecap=10000 19 | queuetimeout=60000 20 | servant=ZipkinTraceApp.ZipkinTraceClient.ZipkinClientObj 21 | shmcap=0 22 | shmkey=0 23 | threads=1 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/ZipkinTraceClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | _ "net/http/pprof" 7 | 8 | "github.com/TarsCloud/TarsGo/contrib/middleware/zipkintracing" 9 | "github.com/TarsCloud/TarsGo/tars" 10 | 11 | "ZipkinTraceClient/tars-protocol/ZipkinTraceApp" 12 | ) 13 | 14 | var ( 15 | sapp = new(ZipkinTraceApp.ZipkinTrace) 16 | logger = tars.GetLogger("zipkin") 17 | ) 18 | 19 | func main() { // Init servant 20 | go func() { 21 | fmt.Println(http.ListenAndServe("0.0.0.0:8090", nil)) 22 | }() 23 | cfg := tars.GetServerConfig() // Get Config File Object 24 | 25 | zipkintracing.Init() 26 | tars.UseClientFilterMiddleware(zipkintracing.ZipkinClientFilter()) 27 | tars.UseServerFilterMiddleware(zipkintracing.ZipkinServerFilter()) 28 | 29 | comm := tars.GetCommunicator() 30 | comm.StringToProxy("ZipkinTraceApp.ZipkinTraceServer.ZipkinTraceObj@tcp -h 127.0.0.1 -p 15015 -t 60000", sapp) 31 | imp := new(ZipkinClientImp) // New Imp 32 | app := new(ZipkinTraceApp.ZipkinClient) // New init the A Tars 33 | app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".ZipkinClientObj") // Register Servant 34 | tars.Run() 35 | } 36 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/client/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/TarsCloud/TarsGo/tars" 7 | 8 | "ZipkinTraceClient/tars-protocol/ZipkinTraceApp" 9 | ) 10 | 11 | func main() { 12 | comm := tars.GetCommunicator() 13 | obj := fmt.Sprintf("ZipkinTraceApp.ZipkinTraceClient.ZipkinClientObj@tcp -h 127.0.0.1 -p 14015 -t 60000") 14 | app := new(ZipkinTraceApp.ZipkinClient) 15 | comm.StringToProxy(obj, app) 16 | var out, i int32 17 | i = 123 18 | ret, err := app.Add(i, i*2, &out) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | fmt.Println(ret, out) 24 | } 25 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/go.mod: -------------------------------------------------------------------------------- 1 | module ZipkinTraceClient 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.0 7 | github.com/TarsCloud/TarsGo/contrib/middleware/zipkintracing v0.0.1 8 | ) 9 | 10 | replace github.com/TarsCloud/TarsGo => ../../../ 11 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/makefile: -------------------------------------------------------------------------------- 1 | APP := ZipkinTraceApp 2 | TARGET := ZipkinTraceClient 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk 10 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceClient/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./ZipkinTraceClient --config=ZipkinTraceClient.conf 4 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/.gitignore: -------------------------------------------------------------------------------- 1 | ZipkinTraceServer 2 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/ZipkinTrace.tars: -------------------------------------------------------------------------------- 1 | module ZipkinTraceApp{ 2 | interface ZipkinTrace{ 3 | int Add(int a,int b,out int c); // Some example function 4 | int Sub(int a,int b,out int c); // Some example function 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/ZipkinTraceImp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "time" 6 | ) 7 | 8 | // ZipkinTraceImp struct 9 | type ZipkinTraceImp struct { 10 | } 11 | 12 | // Add implement 13 | func (imp *ZipkinTraceImp) Add(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 14 | //Doing something in your function 15 | *c = a * b 16 | time.Sleep(500 * time.Millisecond) 17 | //... 18 | return 0, nil 19 | } 20 | 21 | // Sub implement 22 | func (imp *ZipkinTraceImp) Sub(ctx context.Context, a int32, b int32, c *int32) (int32, error) { 23 | //Doing something in your function 24 | *c = a / b 25 | //... 26 | return 0, nil 27 | } 28 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/ZipkinTraceServer.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | app=ZipkinTraceApp 5 | server=ZipkinTraceServer 6 | local=tcp -h 127.0.0.1 -p 15014 -t 30000 7 | logpath=/tmp 8 | samplerate=0.5 9 | sampleaddress=http://127.0.0.1:9411 10 | sampletype=http 11 | sampleencoding=json 12 | 13 | allow 14 | endpoint=tcp -h 127.0.0.1 -p 15015 -t 60000 15 | handlegroup=ZipkinTraceApp.ZipkinTraceServer.ZipkinTraceObjAdapter 16 | maxconns=200000 17 | protocol=tars 18 | queuecap=10000 19 | queuetimeout=60000 20 | servant=ZipkinTraceApp.ZipkinTraceServer.ZipkinTraceObj 21 | shmcap=0 22 | shmkey=0 23 | threads=1 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/ZipkinTraceServer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/TarsCloud/TarsGo/tars" 5 | 6 | "ZipkinTraceServer/tars-protocol/ZipkinTraceApp" 7 | 8 | "github.com/TarsCloud/TarsGo/contrib/middleware/zipkintracing" 9 | ) 10 | 11 | func main() { // Init servant 12 | cfg := tars.GetServerConfig() // Get Config File Object 13 | 14 | zipkintracing.Init() 15 | tars.UseClientFilterMiddleware(zipkintracing.ZipkinClientFilter()) 16 | tars.UseServerFilterMiddleware(zipkintracing.ZipkinServerFilter()) 17 | 18 | imp := new(ZipkinTraceImp) // New Imp 19 | app := new(ZipkinTraceApp.ZipkinTrace) // New init the A Tars 20 | app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".ZipkinTraceObj") // Register Servant 21 | tars.Run() 22 | } 23 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/client/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TarsCloud/TarsGo/cbc345d20356f91e4856da4c732f8399af34d9f4/examples/zipkin/ZipkinTraceServer/client/empty -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/go.mod: -------------------------------------------------------------------------------- 1 | module ZipkinTraceServer 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/TarsCloud/TarsGo v1.4.0 7 | github.com/TarsCloud/TarsGo/contrib/middleware/zipkintracing v0.0.1 8 | ) 9 | 10 | replace github.com/TarsCloud/TarsGo => ../../../ 11 | -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/makefile: -------------------------------------------------------------------------------- 1 | APP := ZipkinTraceApp 2 | TARGET := ZipkinTraceServer 3 | MFLAGS := 4 | DFLAGS := 5 | CONFIG := client 6 | STRIP_FLAG:= N 7 | J2GO_FLAG:= 8 | 9 | -include ../../hack/scripts/makefile.tars.gomod.mk -------------------------------------------------------------------------------- /examples/zipkin/ZipkinTraceServer/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | ./ZipkinTraceServer --config=ZipkinTraceServer.conf 4 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/kr/pretty v0.3.0 // indirect 7 | github.com/rogpeppe/go-internal v1.8.0 // indirect 8 | github.com/stretchr/testify v1.8.4 9 | go.uber.org/automaxprocs v1.5.2 10 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /hack/cmake/CMakeDetermineGoCompiler.cmake: -------------------------------------------------------------------------------- 1 | #if compiler empty then get uri and set CMAKE_GO_COMPILER VAR 2 | if(NOT CMAKE_Go_COMPILER) 3 | if(NOT $ENV{GO_COMPILER} STREQUAL "") #ENV(GO_COMPILER) is empty 4 | get_filename_component(CMAKE_Go_COMPILER_INIT $ENV{GO_COMPILER} PROGRAM PROGRAM_ARGS CMAKE_Go_FLAGS_ENV_INIT) 5 | 6 | if(CMAKE_Go_FLAGS_ENV_INIT) 7 | set(CMAKE_Go_COMPILER_ARG1 "${CMAKE_Go_FLAGS_ENV_INIT}" CACHE STRING "First argument to Go compiler") 8 | endif() 9 | 10 | if(NOT EXISTS ${CMAKE_Go_COMPILER_INIT}) 11 | message(SEND_ERROR "Could not find compiler set in environment variable GO_COMPILER:\n$ENV{GO_COMPILER}.") 12 | endif() 13 | 14 | endif() 15 | 16 | execute_process(COMMAND go env GOPATH OUTPUT_VARIABLE GOPATH) 17 | 18 | string(REGEX REPLACE "\n$" "" GOPATH "${GOPATH}") 19 | 20 | set(Go_BIN_PATH 21 | ${GOPATH} 22 | $ENV{GOPATH} 23 | $ENV{GOROOT} 24 | $ENV{GOROOT}/bin 25 | $ENV{GO_COMPILER} 26 | /usr/bin 27 | /usr/local/bin 28 | ) 29 | 30 | if(CMAKE_Go_COMPILER_INIT) 31 | set(CMAKE_Go_COMPILER ${CMAKE_Go_COMPILER_INIT} CACHE PATH "Go Compiler") 32 | else() 33 | 34 | find_program(CMAKE_Go_COMPILER NAMES go PATHS ${Go_BIN_PATH}) 35 | execute_process (COMMAND ${CMAKE_Go_COMPILER} "version" OUTPUT_VARIABLE GOLANG_VERSION) 36 | 37 | STRING(REGEX MATCH "go[0-9]+.[0-9]+.[0-9]+[ /A-Za-z0-9]*" VERSION "${GOLANG_VERSION}") 38 | message("-- The Golang compiler identification is ${VERSION}") 39 | message("-- Check for working Golang compiler: ${CMAKE_Go_COMPILER}") 40 | endif() 41 | 42 | endif() 43 | 44 | mark_as_advanced(CMAKE_Go_COMPILER) 45 | 46 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeGoCompiler.cmake.in 47 | ${CMAKE_PLATFORM_INFO_DIR}/CMakeGoCompiler.cmake @ONLY) 48 | 49 | set(CMAKE_Go_COMPILER_ENV_VAR "GO_COMPILER") 50 | -------------------------------------------------------------------------------- /hack/cmake/CMakeGoCompiler.cmake.in: -------------------------------------------------------------------------------- 1 | set(CMAKE_Go_COMPILER "@CMAKE_Go_COMPILER@") 2 | set(CMAKE_Go_COMPILER_LOADED 1) 3 | 4 | set(CMAKE_Go_SOURCE_FILE_EXTENSIONS go) 5 | set(CMAKE_Go_LINKER_PREFERENCE 40) 6 | set(CMAKE_Go_OUTPUT_EXTENSION .o) 7 | set(CMAKE_Go_OUTPUT_EXTENSION_REPLACE 1) 8 | set(CMAKE_Go_COMPILER_ENV_VAR "GO_COMPILER") 9 | -------------------------------------------------------------------------------- /hack/cmake/CMakeGoInformation.cmake: -------------------------------------------------------------------------------- 1 | if(NOT CMAKE_Go_COMPILE_OBJECT) 2 | set(CMAKE_Go_COMPILE_OBJECT "go tool compile -l -N -o ") 3 | endif() 4 | 5 | if(NOT CMAKE_Go_LINK_EXECUTABLE) 6 | set(CMAKE_Go_LINK_EXECUTABLE "go tool link -o ") 7 | endif() 8 | -------------------------------------------------------------------------------- /hack/cmake/CMakeTestGoCompiler.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_Go_COMPILER_WORKS 1 CACHE INTERNAL "") 2 | -------------------------------------------------------------------------------- /hack/cmake/golang.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 2 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 3 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 4 | 5 | # go get function 6 | function(ExternalGoProject_Add TARG) 7 | add_custom_target(${TARG} env GOPATH=${GOPATH} ${CMAKE_Go_COMPILER} get ${ARGN}) 8 | endfunction(ExternalGoProject_Add) 9 | 10 | function(add_go_executable NAME) 11 | file(GLOB GO_SOURCE RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.go") 12 | 13 | # message(${GO_SOURCE}) 14 | # message(${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}) 15 | 16 | add_custom_command(OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/.tidy 17 | COMMAND ${CMAKE_Go_COMPILER} mod tidy 18 | COMMENT "${CMAKE_Go_COMPILER} mod tidy" 19 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) 20 | 21 | add_custom_command(OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/.timestamp 22 | COMMAND env GOPATH=${GOPATH} ${CMAKE_Go_COMPILER} build -o "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}" ${CMAKE_GO_FLAGS} ${GO_SOURCE} 23 | COMMENT "${CMAKE_Go_COMPILER} build -o ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME} ${CMAKE_GO_FLAGS} ${GO_SOURCE}" 24 | DEPENDS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/.tidy 25 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) 26 | 27 | add_custom_target(${NAME} ALL DEPENDS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/.timestamp ${ARGN}) 28 | 29 | endfunction(add_go_executable) 30 | 31 | function(ADD_GO_LIBRARY NAME BUILD_TYPE) 32 | if(BUILD_TYPE STREQUAL "STATIC") 33 | set(BUILD_MODE -buildmode=c-archive) 34 | set(LIB_NAME "lib${NAME}.a") 35 | else() 36 | set(BUILD_MODE -buildmode=c-shared) 37 | if(APPLE) 38 | set(LIB_NAME "lib${NAME}.dylib") 39 | else() 40 | set(LIB_NAME "lib${NAME}.so") 41 | endif() 42 | endif() 43 | 44 | file(GLOB GO_SOURCE RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.go") 45 | add_custom_command(OUTPUT ${OUTPUT_DIR}/.tidy 46 | COMMAND ${CMAKE_Go_COMPILER} mod tidy 47 | COMMENT "${CMAKE_Go_COMPILER} mod tidy" 48 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) 49 | 50 | add_custom_command(OUTPUT ${OUTPUT_DIR}/.timestamp 51 | COMMAND env GOPATH=${GOPATH} ${CMAKE_Go_COMPILER} build ${BUILD_MODE} -o "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${LIB_NAME}" ${CMAKE_GO_FLAGS} ${GO_SOURCE} 52 | COMMENT "env GOPATH=${GOPATH} ${CMAKE_Go_COMPILER} build ${BUILD_MODE} -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${LIB_NAME} ${CMAKE_GO_FLAGS} ${GO_SOURCE}" 53 | DEPENDS ${OUTPUT_DIR}/.tidy 54 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) 55 | 56 | add_custom_target(${NAME} ALL DEPENDS ${OUTPUT_DIR}/.timestamp ${ARGN}) 57 | 58 | endfunction(ADD_GO_LIBRARY) 59 | -------------------------------------------------------------------------------- /hack/generate-authors.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.." 5 | 6 | # see also ".mailmap" for how email addresses and names are deduplicated 7 | 8 | { 9 | cat <<-'EOH' 10 | # This file lists all individuals having contributed content to the repository. 11 | # For how it is generated, see `hack/generate-authors.sh`. 12 | EOH 13 | echo 14 | git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf 15 | } > AUTHORS 16 | 17 | -------------------------------------------------------------------------------- /hack/generate-tarsgo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | go-bindata --prefix=hack -o=tars/tools/tarsgo/internal/bindata/bindata.go -pkg=bindata hack/cmake/... hack/scripts/... 4 | -------------------------------------------------------------------------------- /tars/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.swp 3 | -------------------------------------------------------------------------------- /tars/appcache.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import "github.com/TarsCloud/TarsGo/tars/protocol/res/endpointf" 4 | 5 | type AppCache struct { 6 | TarsVersion string 7 | ModifyTime string 8 | LogLevel string 9 | ObjCaches []ObjCache 10 | } 11 | 12 | type ObjCache struct { 13 | Name string 14 | SetID string 15 | Locator string 16 | 17 | Endpoints []endpointf.EndpointF 18 | InactiveEndpoints []endpointf.EndpointF 19 | } 20 | 21 | func GetAppCache() AppCache { 22 | return defaultApp.AppCache() 23 | } 24 | 25 | func (a *application) AppCache() AppCache { 26 | return a.appCache 27 | } 28 | -------------------------------------------------------------------------------- /tars/communicator_test.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/protocol/res/configf" 7 | ) 8 | 9 | func TestStringToProxy(t *testing.T) { 10 | comm := NewCommunicator() 11 | comm.SetProperty("locator", "tars.tarsregistry.QueryObj@tcp -h 172.0.0.1 -t 60000 -p 17890") 12 | prx := new(configf.Config) 13 | comm.StringToProxy("tars.tarsconfig.ConfigObj", prx, WithSet("test.test.1")) 14 | } 15 | -------------------------------------------------------------------------------- /tars/errors.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import "fmt" 4 | 5 | // Error is the type of rpc error with error code 6 | type Error struct { 7 | Code int32 8 | Message string 9 | } 10 | 11 | // Error returns the error message 12 | func (e *Error) Error() string { 13 | return e.Message 14 | } 15 | 16 | // GetErrorCode returns the error code 17 | func GetErrorCode(err error) int32 { 18 | if err == nil { 19 | return 0 20 | } 21 | e, ok := err.(*Error) 22 | if !ok { 23 | return 1 24 | } 25 | return e.Code 26 | } 27 | 28 | // Errorf return the tars.Error instance 29 | func Errorf(code int32, format string, args ...interface{}) *Error { 30 | return &Error{Code: code, Message: fmt.Sprintf(format, args...)} 31 | } 32 | -------------------------------------------------------------------------------- /tars/hash_func.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | // https://github.com/TarsCloud/TarsCpp/blob/master/util/include/util/tc_hash_fun.h 4 | 5 | func HashString(str string) uint32 { 6 | var h uint32 7 | for _, c := range str { 8 | h = 5*h + uint32(c) 9 | } 10 | return h 11 | } 12 | 13 | func Hash(str string) uint32 { 14 | var h uint32 15 | for _, c := range str { 16 | h = (h << 4) + uint32(c) 17 | if g := h & 0xF0000000; g != 0 { 18 | h = h ^ (g >> 24) 19 | h = h ^ g 20 | } 21 | } 22 | return h 23 | } 24 | 25 | func HashNew(str string) uint32 { 26 | var value uint32 27 | for _, c := range str { 28 | value += uint32(c) 29 | value += value << 10 30 | value ^= value >> 6 31 | } 32 | value += value << 3 33 | value ^= value >> 11 34 | value += value << 15 35 | if value == 0 { 36 | return 1 37 | } 38 | return value 39 | } 40 | 41 | func MagicStringHash(str string) uint32 { 42 | return HashNew(str) 43 | } 44 | -------------------------------------------------------------------------------- /tars/hash_func_test.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import "testing" 4 | 5 | func TestHashNew(t *testing.T) { 6 | testCases := []struct { 7 | name string 8 | roomId string 9 | wantHash uint32 10 | }{ 11 | { 12 | name: "#12723353", 13 | roomId: "#12723353", 14 | wantHash: 1476478819, 15 | }, 16 | { 17 | name: "#12723353_native", 18 | roomId: "#12723353_native", 19 | wantHash: 268793112, 20 | }, 21 | } 22 | for _, tt := range testCases { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if code := HashNew(tt.roomId); code != tt.wantHash { 25 | t.Errorf("HashNew() = %v, want %v", code, tt.wantHash) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tars/message.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/protocol/res/requestf" 7 | "github.com/TarsCloud/TarsGo/tars/selector" 8 | ) 9 | 10 | // HashType is the hash type 11 | type HashType int 12 | 13 | // HashType enum 14 | const ( 15 | ModHash HashType = iota 16 | ConsistentHash 17 | ) 18 | 19 | // Message is a struct contains servant information 20 | type Message struct { 21 | Req *requestf.RequestPacket 22 | Resp *requestf.ResponsePacket 23 | 24 | Ser *ServantProxy 25 | Adp *AdapterProxy 26 | 27 | BeginTime int64 28 | EndTime int64 29 | Status int32 30 | 31 | hashCode uint32 32 | hashType HashType 33 | isHash bool 34 | } 35 | 36 | // Init define the beginTime 37 | func (m *Message) Init() { 38 | m.BeginTime = time.Now().UnixNano() / 1e6 39 | } 40 | 41 | // End define the endTime 42 | func (m *Message) End() { 43 | m.EndTime = time.Now().UnixNano() / 1e6 44 | } 45 | 46 | // Cost calculate the cost time 47 | func (m *Message) Cost() int64 { 48 | return m.EndTime - m.BeginTime 49 | } 50 | 51 | // SetHash set hash code 52 | func (m *Message) SetHash(code uint32, h HashType) { 53 | m.hashCode = code 54 | m.hashType = h 55 | m.isHash = true 56 | } 57 | 58 | func (m *Message) HashCode() uint32 { 59 | return m.hashCode 60 | } 61 | 62 | func (m *Message) HashType() selector.HashType { 63 | return selector.HashType(m.hashType) 64 | } 65 | 66 | func (m *Message) IsHash() bool { 67 | return m.isHash 68 | } 69 | -------------------------------------------------------------------------------- /tars/model/servant.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/util/endpoint" 7 | 8 | "github.com/TarsCloud/TarsGo/tars/protocol/res/requestf" 9 | ) 10 | 11 | // Servant is interface for call the remote server. 12 | type Servant interface { 13 | Name() string 14 | TarsInvoke(ctx context.Context, cType byte, 15 | sFuncName string, 16 | buf []byte, 17 | status map[string]string, 18 | context map[string]string, 19 | resp *requestf.ResponsePacket) error 20 | TarsSetTimeout(t int) 21 | TarsSetProtocol(Protocol) 22 | Endpoints() []*endpoint.Endpoint 23 | SetPushCallback(callback func([]byte)) 24 | } 25 | 26 | type Protocol interface { 27 | RequestPack(*requestf.RequestPacket) ([]byte, error) 28 | ResponseUnpack([]byte) (*requestf.ResponsePacket, error) 29 | ParsePackage([]byte) (int, int) 30 | } 31 | -------------------------------------------------------------------------------- /tars/nodef.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/protocol/res/nodef" 7 | ) 8 | 9 | // NodeFHelper is helper struct. 10 | type NodeFHelper struct { 11 | comm *Communicator 12 | si nodef.ServerInfo 13 | sf *nodef.ServerF 14 | } 15 | 16 | // SetNodeInfo sets node information with communicator, node name, app name, server and container name 17 | func (n *NodeFHelper) SetNodeInfo(comm *Communicator, node string, app string, server string, container string) { 18 | if node == "" { 19 | return 20 | } 21 | n.comm = comm 22 | n.sf = new(nodef.ServerF) 23 | comm.StringToProxy(node, n.sf) 24 | n.si = nodef.ServerInfo{ 25 | Application: app, 26 | ServerName: server, 27 | Pid: int32(os.Getpid()), 28 | Adapter: "", 29 | } 30 | } 31 | 32 | // KeepAlive sends the keepalive package to the node. 33 | func (n *NodeFHelper) KeepAlive(adapter string) { 34 | if n.sf == nil { 35 | return 36 | } 37 | n.si.Pid = int32(os.Getpid()) 38 | n.si.Adapter = adapter 39 | _, err := n.sf.KeepAlive(&n.si, n.comm.Client.Context()) 40 | if err != nil { 41 | TLOG.Error("keepalive fail:", adapter) 42 | } 43 | } 44 | 45 | // ReportVersion report the tars version to the node. 46 | func (n *NodeFHelper) ReportVersion(version string) { 47 | if n.sf == nil { 48 | return 49 | } 50 | _, err := n.sf.ReportVersion(n.si.Application, n.si.ServerName, version, n.comm.Client.Context()) 51 | if err != nil { 52 | TLOG.Error("report Version fail:") 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tars/notifyf.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import "github.com/TarsCloud/TarsGo/tars/protocol/res/notifyf" 4 | 5 | const ( 6 | NotifyNormal = 0 7 | NotifyWarn = 1 8 | NotifyError = 2 9 | ) 10 | 11 | // NotifyHelper is the helper struct for the Notify service. 12 | type NotifyHelper struct { 13 | comm *Communicator 14 | tn *notifyf.Notify 15 | tm notifyf.ReportInfo 16 | } 17 | 18 | // SetNotifyInfo sets the communicator's notify info with communicator, notify name, app name, server name, and container name 19 | func (n *NotifyHelper) SetNotifyInfo(comm *Communicator, notify string, app string, server string, container string) { 20 | n.comm = comm 21 | n.tn = new(notifyf.Notify) 22 | comm.StringToProxy(notify, n.tn) 23 | var set string 24 | if v, ok := comm.GetProperty("setdivision"); ok { 25 | set = v 26 | } 27 | n.tm = notifyf.ReportInfo{ 28 | EType: 0, 29 | SApp: app, 30 | SSet: set, 31 | SContainer: container, 32 | SServer: server, 33 | SMessage: "", 34 | SThreadId: "", 35 | ELevel: 0, 36 | } 37 | } 38 | 39 | // ReportNotifyInfo reports notify information with level and info 40 | func (n *NotifyHelper) ReportNotifyInfo(level int32, info string) { 41 | n.tm.ELevel = notifyf.NOTIFYLEVEL(level) 42 | n.tm.SMessage = info 43 | TLOG.Debug(n.tm) 44 | if err := n.tn.ReportNotifyInfo(&n.tm, n.comm.Client.Context()); err != nil { 45 | TLOG.Errorf("ReportNotifyInfo err: %v", err) 46 | } 47 | } 48 | 49 | // ReportNotifyInfo reports notify information with level and info 50 | func ReportNotifyInfo(level int32, info string) { 51 | svrCfg := GetServerConfig() 52 | if svrCfg.Notify == "" { 53 | return 54 | } 55 | comm := GetCommunicator() 56 | ha := new(NotifyHelper) 57 | ha.SetNotifyInfo(comm, svrCfg.Notify, svrCfg.App, svrCfg.Server, svrCfg.Container) 58 | defer func() { 59 | if err := recover(); err != nil { 60 | TLOG.Debug(err) 61 | } 62 | }() 63 | ha.ReportNotifyInfo(level, info) 64 | } 65 | -------------------------------------------------------------------------------- /tars/options.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import "github.com/TarsCloud/TarsGo/tars/registry" 4 | 5 | type Option func(o *options) 6 | 7 | type options struct { 8 | registrar registry.Registrar 9 | } 10 | 11 | // Registrar returns an Option to use the Registrar 12 | func Registrar(r registry.Registrar) Option { 13 | return func(o *options) { 14 | o.registrar = r 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tars/panic.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/TarsCloud/TarsGo/tars/util/debug" 8 | "github.com/TarsCloud/TarsGo/tars/util/rogger" 9 | ) 10 | 11 | // CheckPanic used to dump stack info to file when catch panic 12 | func CheckPanic() { 13 | if r := recover(); r != nil { 14 | var msg string 15 | if err, ok := r.(error); ok { 16 | msg = err.Error() 17 | } else { 18 | msg = fmt.Sprintf("%#v", r) 19 | } 20 | debug.DumpStack(true, "panic", msg) 21 | rogger.FlushLogger() 22 | os.Exit(-1) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tars/protocol/protoconst.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | const ( 4 | PackageLess = iota 5 | PackageFull 6 | PackageError 7 | ) 8 | -------------------------------------------------------------------------------- /tars/protocol/push/client.go: -------------------------------------------------------------------------------- 1 | package push 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/model" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/requestf" 8 | "github.com/TarsCloud/TarsGo/tars/util/tools" 9 | ) 10 | 11 | // Client is the pushing client 12 | type Client struct { 13 | servant model.Servant 14 | callback func(data []byte) 15 | } 16 | 17 | // SetServant implements client servant 18 | func (c *Client) SetServant(s model.Servant) { 19 | s.SetPushCallback(c.callback) 20 | c.servant = s 21 | } 22 | 23 | // NewClient returns the client for pushing message 24 | func NewClient(callback func(data []byte)) *Client { 25 | return &Client{callback: callback} 26 | } 27 | 28 | // Connect starts to connect to pushing server 29 | func (c *Client) Connect(req []byte) ([]byte, error) { 30 | rsp := &requestf.ResponsePacket{} 31 | if err := c.servant.TarsInvoke(context.Background(), 0, "push", req, nil, nil, rsp); err != nil { 32 | return nil, err 33 | } 34 | return tools.Int8ToByte(rsp.SBuffer), nil 35 | } 36 | -------------------------------------------------------------------------------- /tars/protocol/push/server.go: -------------------------------------------------------------------------------- 1 | package push 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "encoding/binary" 7 | "fmt" 8 | "net" 9 | 10 | "github.com/TarsCloud/TarsGo/tars" 11 | "github.com/TarsCloud/TarsGo/tars/protocol/codec" 12 | "github.com/TarsCloud/TarsGo/tars/protocol/res/requestf" 13 | "github.com/TarsCloud/TarsGo/tars/transport" 14 | "github.com/TarsCloud/TarsGo/tars/util/current" 15 | "github.com/TarsCloud/TarsGo/tars/util/tools" 16 | ) 17 | 18 | // PushServer defines the pushing server 19 | type PushServer interface { 20 | OnConnect(ctx context.Context, req []byte) []byte 21 | OnClose(ctx context.Context) 22 | } 23 | 24 | type serverProtocol struct { 25 | tars.Protocol 26 | s PushServer 27 | } 28 | 29 | // Send push message to client 30 | func Send(ctx context.Context, data []byte) error { 31 | conn, udpAddr, ok := current.GetRawConn(ctx) 32 | if !ok { 33 | return fmt.Errorf("connection not found") 34 | } 35 | rsp := &requestf.ResponsePacket{ 36 | SBuffer: tools.ByteToInt8(data), 37 | } 38 | rspData := response2Bytes(rsp) 39 | var err error 40 | if udpAddr != nil { 41 | udpConn, _ := conn.(*net.UDPConn) 42 | _, err = udpConn.WriteToUDP(rspData, udpAddr) 43 | } else { 44 | _, err = conn.Write(rspData) 45 | } 46 | return err 47 | } 48 | 49 | // NewServer return a server for pushing message 50 | func NewServer(s PushServer) transport.ServerProtocol { 51 | return &serverProtocol{Protocol: tars.Protocol{}, s: s} 52 | } 53 | 54 | func (s *serverProtocol) DoClose(ctx context.Context) { 55 | s.s.OnClose(ctx) 56 | } 57 | 58 | // Invoke process request and send response 59 | func (s *serverProtocol) Invoke(ctx context.Context, reqBytes []byte) []byte { 60 | req := &requestf.RequestPacket{} 61 | rsp := &requestf.ResponsePacket{} 62 | is := codec.NewReader(reqBytes[4:]) 63 | if err := req.ReadFrom(is); err != nil { 64 | rsp.IRet = 1 65 | rsp.SResultDesc = "decode request package error" 66 | } else { 67 | rsp.IVersion = req.IVersion 68 | rsp.CPacketType = req.CPacketType 69 | rsp.IRequestId = req.IRequestId 70 | if req.SFuncName != "tars_ping" { 71 | rspData := s.s.OnConnect(ctx, tools.Int8ToByte(req.SBuffer)) 72 | rsp.SBuffer = tools.ByteToInt8(rspData) 73 | } 74 | } 75 | return response2Bytes(rsp) 76 | } 77 | 78 | func response2Bytes(rsp *requestf.ResponsePacket) []byte { 79 | os := codec.NewBuffer() 80 | rsp.WriteTo(os) 81 | bs := os.ToBytes() 82 | sbuf := bytes.NewBuffer(nil) 83 | sbuf.Write(make([]byte, 4)) 84 | sbuf.Write(bs) 85 | len := sbuf.Len() 86 | binary.BigEndian.PutUint32(sbuf.Bytes(), uint32(len)) 87 | return sbuf.Bytes() 88 | } 89 | -------------------------------------------------------------------------------- /tars/protocol/res/AdminF.tars: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making Tars available. 3 | * 4 | * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. 5 | * 6 | * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * https://opensource.org/licenses/BSD-3-Clause 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed 12 | * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 13 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the 14 | * specific language governing permissions and limitations under the License. 15 | */ 16 | 17 | module adminf 18 | { 19 | interface AdminF 20 | { 21 | /** 22 | * 关闭服务 23 | */ 24 | void shutdown(); 25 | 26 | /** 27 | * 通知服务 28 | */ 29 | string notify(string command); 30 | }; 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /tars/protocol/res/EndpointF.tars: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making Tars available. 3 | * 4 | * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. 5 | * 6 | * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * https://opensource.org/licenses/BSD-3-Clause 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed 12 | * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 13 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the 14 | * specific language governing permissions and limitations under the License. 15 | */ 16 | 17 | module endpointf 18 | { 19 | /** 20 | * 端口信息 21 | */ 22 | struct EndpointF 23 | { 24 | 0 require string host; 25 | 1 require int port; 26 | 2 require int timeout; 27 | 3 require int istcp; 28 | 4 require int grid; 29 | 5 optional int groupworkid; 30 | 6 optional int grouprealid; 31 | 7 optional string setId; 32 | 8 optional int qos; 33 | 9 optional int bakFlag; 34 | 11 optional int weight; 35 | 12 optional int weightType; 36 | 13 optional int authType; 37 | }; 38 | key[EndpointF, host, port, timeout, istcp, grid, qos, weight, weightType, authType]; 39 | }; 40 | 41 | 42 | -------------------------------------------------------------------------------- /tars/protocol/res/LogF.tars: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making Tars available. 3 | * 4 | * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. 5 | * 6 | * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * https://opensource.org/licenses/BSD-3-Clause 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed 12 | * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 13 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the 14 | * specific language governing permissions and limitations under the License. 15 | */ 16 | 17 | module logf 18 | { 19 | struct LogInfo 20 | { 21 | //业务名称 22 | 0 require string appname; 23 | //服务名称 24 | 1 require string servername; 25 | //日志文件名称 26 | 2 require string sFilename; 27 | //时间格式 28 | 3 require string sFormat; 29 | //set分组名称 30 | 4 optional string setdivision; 31 | // 日志文件名是否带.log后缀 32 | 5 optional bool bHasSufix=true; 33 | // 是否允许框架在日志文件名上增加业务相关的标识 34 | 6 optional bool bHasAppNamePrefix=true; 35 | // 框架内部的日期和时间部分是否加上[]符号 36 | 7 optional bool bHasSquareBracket=false; 37 | // 日志文件名中用户自定义字符与日期字符间的连接符,默认是"_" 38 | 8 optional string sConcatStr="_"; 39 | // 日志内容项之间的分隔符,默认是"|" 40 | 9 optional string sSepar="|"; 41 | //按天/小时/分钟输出日志时的记录类型,例如,按一天:day或者1day;按两小时:2hour;按10分钟:10minute 42 | 10 optional string sLogType = ""; 43 | }; 44 | interface Log 45 | { 46 | /** 47 | * 记录远程日志 48 | * @param app, 应用名称 49 | * @param server, 服务名称 50 | * @param file, 文件名称 51 | * @param format, 日志时间格式(%Y%m%d) 52 | * @param buffer, 日志内容 53 | */ 54 | void logger(string app, string server, string file, string format, vector buffer); 55 | 56 | /** 57 | * 记录远程日志 58 | * @param info, LogInfo 59 | * @param buffer, 日志内容 60 | */ 61 | void loggerbyInfo(LogInfo info, vector buffer); 62 | }; 63 | }; 64 | -------------------------------------------------------------------------------- /tars/protocol/res/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | tars2go -without-trace=true -add-servant=false -tarsPath github.com/TarsCloud/TarsGo/tars -module github.com/TarsCloud/TarsGo/tars/protocol/res *.tars 3 | -------------------------------------------------------------------------------- /tars/protocol/res/NodeF.tars: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making Tars available. 3 | * 4 | * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. 5 | * 6 | * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * https://opensource.org/licenses/BSD-3-Clause 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed 12 | * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 13 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the 14 | * specific language governing permissions and limitations under the License. 15 | */ 16 | 17 | module nodef 18 | { 19 | struct ServerInfo 20 | { 21 | 0 require string application; 22 | 1 require string serverName; 23 | 2 require int pid; 24 | 3 optional string adapter; 25 | }; 26 | 27 | interface ServerF 28 | { 29 | /** 30 | * 向node定时上报serverInfo 31 | * @param serverInfo 服务状态 32 | * @return int 33 | */ 34 | int keepAlive(ServerInfo serverInfo); 35 | 36 | /** 37 | * 向node定时上报serverInfo(Activing状态) 38 | * @param serverInfo 服务状态 39 | * @return int 40 | */ 41 | int keepActiving(ServerInfo serverInfo); 42 | 43 | /** 44 | * 向node上报TARS版本信息 45 | * @param string 版本信息 46 | * @return int 47 | */ 48 | int reportVersion(string app,string serverName,string version); 49 | 50 | /** 51 | * 获取最近keepalive的时间戳 52 | * @return 最后一次keepalive的时间戳 53 | */ 54 | unsigned int getLatestKeepAliveTime(); 55 | }; 56 | }; -------------------------------------------------------------------------------- /tars/protocol/res/PropertyF.tars: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making Tars available. 3 | * 4 | * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. 5 | * 6 | * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * https://opensource.org/licenses/BSD-3-Clause 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed 12 | * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 13 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the 14 | * specific language governing permissions and limitations under the License. 15 | */ 16 | 17 | module propertyf 18 | { 19 | 20 | //属性上报消息包 Prop = property 21 | struct StatPropMsgHead 22 | { 23 | 0 require string moduleName; //模块name 24 | 1 require string ip; //ip 25 | 2 require string propertyName; //属性name 26 | 3 optional string setName; //set名 27 | 4 optional string setArea; //set地区名 28 | 5 optional string setID; //set组名 29 | 6 optional string sContainer; //容器名 30 | 7 optional int iPropertyVer=1; //协议版本 31 | }; 32 | 33 | key[StatPropMsgHead, moduleName, ip, propertyName, setName, setArea, setID ]; 34 | 35 | //属性值信息 36 | struct StatPropInfo 37 | { 38 | 0 require string policy; //Sum\Avg\Distr\Count\Max\Min 39 | 1 require string value; //值 40 | }; 41 | 42 | //属性上报包体 43 | struct StatPropMsgBody 44 | { 45 | 0 require vector vInfo; //上报信息 46 | }; 47 | 48 | /** 49 | * 50 | * 上报服务的接口 51 | * 52 | **/ 53 | interface PropertyF 54 | { 55 | /** 56 | * 上报属性统计信息 Prop = property 57 | * @param statmsg, 上报信息 58 | * @return int, 返回0表示成功 59 | */ 60 | int reportPropMsg( map statmsg ); 61 | }; 62 | 63 | 64 | }; 65 | -------------------------------------------------------------------------------- /tars/protocol/res/RequestF.tars: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making Tars available. 3 | * 4 | * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. 5 | * 6 | * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 7 | * in compliance with the License. You may obtain a copy of the License at 8 | * 9 | * https://opensource.org/licenses/BSD-3-Clause 10 | * 11 | * Unless required by applicable law or agreed to in writing, software distributed 12 | * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 13 | * CONDITIONS OF ANY KIND, either express or implied. See the License for the 14 | * specific language governing permissions and limitations under the License. 15 | */ 16 | 17 | module requestf 18 | { 19 | //请求包体 20 | struct RequestPacket 21 | { 22 | 1 require short iVersion; 23 | 2 require byte cPacketType = 0; 24 | 3 require int iMessageType = 0; 25 | 4 require int iRequestId; 26 | 5 require string sServantName = ""; 27 | 6 require string sFuncName = ""; 28 | 7 require vector sBuffer; 29 | 8 require int iTimeout = 0; 30 | 9 require map context; 31 | 10 require map status; 32 | }; 33 | 34 | //响应包体 35 | struct ResponsePacket 36 | { 37 | 1 require short iVersion; 38 | 2 require byte cPacketType = 0; 39 | 3 require int iRequestId; 40 | 4 require int iMessageType = 0; 41 | 5 require int iRet = 0; 42 | 6 require vector sBuffer; 43 | 7 require map status; 44 | 8 optional string sResultDesc; 45 | 9 optional map context; 46 | }; 47 | }; 48 | -------------------------------------------------------------------------------- /tars/protocol/res/basef/BaseF.go: -------------------------------------------------------------------------------- 1 | // Code generated by tars2go 1.2.3, DO NOT EDIT. 2 | // This file was generated from BaseF.tars 3 | // Package basef comment 4 | package basef 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/TarsCloud/TarsGo/tars/protocol/codec" 10 | ) 11 | 12 | // Reference imports to suppress errors if they are not otherwise used. 13 | var _ = fmt.Errorf 14 | var _ = codec.FromInt8 15 | 16 | //const as define in tars file 17 | const ( 18 | TARSVERSION int16 = 0x01 19 | TUPVERSION int16 = 0x03 20 | XMLVERSION int16 = 0x04 21 | JSONVERSION int16 = 0x05 22 | TARSNORMAL int8 = 0x00 23 | TARSONEWAY int8 = 0x01 24 | TARSSERVERSUCCESS int32 = 0 25 | TARSSERVERDECODEERR int32 = -1 26 | TARSSERVERENCODEERR int32 = -2 27 | TARSSERVERNOFUNCERR int32 = -3 28 | TARSSERVERNOSERVANTERR int32 = -4 29 | TARSSERVERRESETGRID int32 = -5 30 | TARSSERVERQUEUETIMEOUT int32 = -6 31 | TARSASYNCCALLTIMEOUT int32 = -7 32 | TARSINVOKETIMEOUT int32 = -7 33 | TARSPROXYCONNECTERR int32 = -8 34 | TARSSERVEROVERLOAD int32 = -9 35 | TARSADAPTERNULL int32 = -10 36 | TARSINVOKEBYINVALIDESET int32 = -11 37 | TARSCLIENTDECODEERR int32 = -12 38 | TARSSENDREQUESTERR int32 = -13 39 | TARSSERVERUNKNOWNERR int32 = -99 40 | TARSMESSAGETYPENULL int32 = 0x00 41 | TARSMESSAGETYPEHASH int32 = 0x01 42 | TARSMESSAGETYPEGRID int32 = 0x02 43 | TARSMESSAGETYPEDYED int32 = 0x04 44 | TARSMESSAGETYPESAMPLE int32 = 0x08 45 | TARSMESSAGETYPEASYNC int32 = 0x10 46 | TARSMESSAGETYPESETNAME int32 = 0x80 47 | TARSMESSAGETYPETRACE int32 = 0x100 48 | ) 49 | -------------------------------------------------------------------------------- /tars/protocol/res/requestf/request.go: -------------------------------------------------------------------------------- 1 | package requestf 2 | 3 | // AddMessageType add message type t to message 4 | func (st *RequestPacket) AddMessageType(t int32) { 5 | st.IMessageType = st.IMessageType | t 6 | } 7 | 8 | // HasMessageType check whether message contain type t 9 | func (st *RequestPacket) HasMessageType(t int32) bool { 10 | return st.IMessageType&t != 0 11 | } 12 | -------------------------------------------------------------------------------- /tars/protocol/tarsprotocol.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import ( 4 | "encoding/binary" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/protocol/codec" 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/requestf" 8 | ) 9 | 10 | var maxPackageLength int = 10485760 11 | 12 | // SetMaxPackageLength sets the max length of tars packet 13 | func SetMaxPackageLength(len int) { 14 | maxPackageLength = len 15 | } 16 | 17 | func TarsRequest(rev []byte) (int, int) { 18 | if len(rev) < 4 { 19 | return 0, PackageLess 20 | } 21 | iHeaderLen := int(binary.BigEndian.Uint32(rev[0:4])) 22 | if iHeaderLen < 4 || iHeaderLen > maxPackageLength { 23 | return 0, PackageError 24 | } 25 | if len(rev) < iHeaderLen { 26 | return 0, PackageLess 27 | } 28 | return iHeaderLen, PackageFull 29 | } 30 | 31 | type TarsProtocol struct{} 32 | 33 | func (p *TarsProtocol) RequestPack(req *requestf.RequestPacket) ([]byte, error) { 34 | os := codec.NewBuffer() 35 | err := os.WriteSliceInt8(make([]int8, 4)) 36 | if err != nil { 37 | return nil, err 38 | } 39 | err = req.WriteTo(os) 40 | if err != nil { 41 | return nil, err 42 | } 43 | bs := os.ToBytes() 44 | l := len(bs) 45 | binary.BigEndian.PutUint32(bs, uint32(l)) 46 | return bs, nil 47 | 48 | } 49 | 50 | func (p *TarsProtocol) ResponseUnpack(pkg []byte) (*requestf.ResponsePacket, error) { 51 | packet := &requestf.ResponsePacket{} 52 | err := packet.ReadFrom(codec.NewReader(pkg[4:])) 53 | return packet, err 54 | } 55 | 56 | func (p *TarsProtocol) ParsePackage(rev []byte) (int, int) { 57 | return TarsRequest(rev) 58 | } 59 | -------------------------------------------------------------------------------- /tars/registry.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/registry" 7 | "github.com/TarsCloud/TarsGo/tars/util/endpoint" 8 | ) 9 | 10 | func (a *application) registryAdapters(ctx context.Context) { 11 | if a.opt.registrar == nil { 12 | return 13 | } 14 | svrCfg := GetServerConfig() 15 | for _, adapter := range svrCfg.Adapters { 16 | servant := ®istry.ServantInstance{ 17 | TarsVersion: Version, 18 | App: svrCfg.App, 19 | Server: svrCfg.Server, 20 | Servant: adapter.Obj, 21 | EnableSet: svrCfg.Enableset, 22 | SetDivision: svrCfg.Setdivision, 23 | Protocol: adapter.Protocol, 24 | Endpoint: endpoint.Endpoint2tars(adapter.Endpoint), 25 | } 26 | if err := a.opt.registrar.Registry(ctx, servant); err != nil { 27 | TLOG.Errorf("registry %+v error: %+v", servant, err) 28 | } 29 | } 30 | } 31 | 32 | func (a *application) deregisterAdapters(ctx context.Context) { 33 | if a.opt.registrar == nil { 34 | return 35 | } 36 | svrCfg := GetServerConfig() 37 | for _, adapter := range svrCfg.Adapters { 38 | servant := ®istry.ServantInstance{ 39 | TarsVersion: Version, 40 | App: svrCfg.App, 41 | Server: svrCfg.Server, 42 | EnableSet: svrCfg.Enableset, 43 | SetDivision: svrCfg.Setdivision, 44 | Servant: adapter.Obj, 45 | Protocol: adapter.Protocol, 46 | Endpoint: endpoint.Endpoint2tars(adapter.Endpoint), 47 | } 48 | if err := a.opt.registrar.Deregister(ctx, servant); err != nil { 49 | TLOG.Errorf("deregister: %+v error: %+v", servant, err) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tars/registry/registry.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/protocol/res/endpointf" 7 | ) 8 | 9 | type Endpoint = endpointf.EndpointF 10 | 11 | // ServantInstance is an instance of a service in a discovery system. 12 | type ServantInstance struct { 13 | TarsVersion string `json:"tars_version"` 14 | App string `json:"app"` 15 | Server string `json:"server"` 16 | EnableSet bool `json:"enable_set"` 17 | SetDivision string `json:"set_division"` 18 | Protocol string `json:"protocol"` 19 | Servant string `json:"servant"` 20 | Endpoint Endpoint `json:"endpoint"` 21 | } 22 | 23 | // Registrar is service registrar. 24 | type Registrar interface { 25 | Registry(ctx context.Context, servant *ServantInstance) error 26 | Deregister(ctx context.Context, servant *ServantInstance) error 27 | // QueryServant service discovery 28 | QueryServant(ctx context.Context, id string) (activeEp []Endpoint, inactiveEp []Endpoint, err error) 29 | QueryServantBySet(ctx context.Context, id, set string) (activeEp []Endpoint, inactiveEp []Endpoint, err error) 30 | } 31 | -------------------------------------------------------------------------------- /tars/registry/tars/registry.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/TarsCloud/TarsGo/tars/protocol/res/queryf" 8 | "github.com/TarsCloud/TarsGo/tars/registry" 9 | ) 10 | 11 | type Context interface { 12 | Context() map[string]string 13 | } 14 | 15 | type tarsRegistry struct { 16 | query *queryf.QueryF 17 | ctx Context 18 | } 19 | 20 | func New(query *queryf.QueryF, ctx Context) registry.Registrar { 21 | return &tarsRegistry{query: query, ctx: ctx} 22 | } 23 | 24 | func (t *tarsRegistry) Registry(_ context.Context, _ *registry.ServantInstance) error { 25 | return nil 26 | } 27 | 28 | func (t *tarsRegistry) Deregister(_ context.Context, _ *registry.ServantInstance) error { 29 | return nil 30 | } 31 | 32 | func (t *tarsRegistry) QueryServant(ctx context.Context, id string) (activeEp []registry.Endpoint, inactiveEp []registry.Endpoint, err error) { 33 | ret, err := t.query.FindObjectByIdInSameGroupWithContext(ctx, id, &activeEp, &inactiveEp, t.ctx.Context()) 34 | if err != nil { 35 | return nil, nil, err 36 | } 37 | if ret != 0 { 38 | return nil, nil, fmt.Errorf("QueryServant id: %s fail, ret: %d", id, ret) 39 | } 40 | return activeEp, inactiveEp, nil 41 | } 42 | 43 | func (t *tarsRegistry) QueryServantBySet(ctx context.Context, id, set string) (activeEp []registry.Endpoint, inactiveEp []registry.Endpoint, err error) { 44 | ret, err := t.query.FindObjectByIdInSameSetWithContext(ctx, id, set, &activeEp, &inactiveEp, t.ctx.Context()) 45 | if err != nil { 46 | return nil, nil, err 47 | } 48 | if ret != 0 { 49 | return nil, nil, fmt.Errorf("QueryServantBySet id: %s, setId: %s fail, ret: %d", id, set, ret) 50 | } 51 | return activeEp, inactiveEp, nil 52 | } 53 | -------------------------------------------------------------------------------- /tars/selector/consistenthash/consistenthash_new_test.go: -------------------------------------------------------------------------------- 1 | package consistenthash 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/util/endpoint" 7 | ) 8 | 9 | func TestHash(t *testing.T) { 10 | k := KetamaHashAlg{} 11 | t.Log(k.Hash("1.1.1.1")) 12 | d := DefaultHashAlg{} 13 | t.Log(d.Hash("1.1.1.1")) 14 | } 15 | 16 | func TestConsistentHash(t *testing.T) { 17 | ch := New(false, DefaultHash) 18 | ch.Add(endpoint.Endpoint{ 19 | Host: "10.160.129.102", 20 | Qos: 2, 21 | }) 22 | ch.Add(endpoint.Endpoint{ 23 | Host: "10.160.129.105", 24 | Qos: 1, 25 | }) 26 | ch.printNode() 27 | ep, _ := ch.FindInt32(hashFn("#12723353")) 28 | t.Log("#12723353", hashFn("#12723353"), ep.Host) 29 | ep, _ = ch.FindInt32(hashFn("#12723353_native")) 30 | t.Log("#12723353_native", hashFn("#12723353_native"), ep.Host) 31 | } 32 | 33 | func TestKetamaHashAlg_Hash(t *testing.T) { 34 | tests := []struct { 35 | name string 36 | str string 37 | want uint32 38 | }{ 39 | { 40 | name: "1.1.1.1", 41 | str: "1.1.1.1", 42 | want: 329942752, 43 | }, 44 | { 45 | name: "2.2.2.2", 46 | str: "2.2.2.2", 47 | want: 329942752, 48 | }, 49 | } 50 | for _, tt := range tests { 51 | t.Run(tt.name, func(t *testing.T) { 52 | k := KetamaHashAlg{} 53 | if code := k.Hash(tt.str); code != tt.want { 54 | t.Errorf("Hash() = %v, want %v", code, tt.want) 55 | } 56 | }) 57 | } 58 | } 59 | 60 | func hashFn(str string) uint32 { 61 | var value uint32 62 | for _, c := range str { 63 | value += uint32(c) 64 | value += value << 10 65 | value ^= value >> 6 66 | } 67 | value += value << 3 68 | value ^= value >> 11 69 | value += value << 15 70 | if value == 0 { 71 | return 1 72 | } 73 | return value 74 | } 75 | -------------------------------------------------------------------------------- /tars/selector/modhash/modhash.go: -------------------------------------------------------------------------------- 1 | package modhash 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "sync" 7 | 8 | "github.com/TarsCloud/TarsGo/tars/selector" 9 | "github.com/TarsCloud/TarsGo/tars/util/endpoint" 10 | ) 11 | 12 | type ModHash struct { 13 | sync.RWMutex 14 | enableWeight bool 15 | mapValues map[string]struct{} 16 | endpoints []endpoint.Endpoint 17 | staticWeightRouterCache []int 18 | } 19 | 20 | var _ selector.Selector = (*ModHash)(nil) 21 | 22 | func New(enableWeight bool) *ModHash { 23 | return &ModHash{ 24 | enableWeight: enableWeight, 25 | mapValues: make(map[string]struct{}), 26 | } 27 | } 28 | 29 | func (m *ModHash) Select(msg selector.Message) (endpoint.Endpoint, error) { 30 | m.RLock() 31 | defer m.RUnlock() 32 | var ep endpoint.Endpoint 33 | if len(m.endpoints) == 0 { 34 | return ep, errors.New("modhash: no such endpoint.Endpoint") 35 | } 36 | hashCode := msg.HashCode() 37 | if len(m.staticWeightRouterCache) != 0 { 38 | idx := m.staticWeightRouterCache[hashCode%uint32(len(m.staticWeightRouterCache))] 39 | return m.endpoints[idx], nil 40 | } 41 | return m.endpoints[hashCode%uint32(len(m.endpoints))], nil 42 | } 43 | 44 | func (m *ModHash) Refresh(eps []endpoint.Endpoint) { 45 | m.Lock() 46 | defer m.Unlock() 47 | m.mapValues = make(map[string]struct{}, len(eps)) 48 | m.endpoints = make([]endpoint.Endpoint, 0, len(eps)) 49 | for _, ep := range eps { 50 | m.addLocked(ep) 51 | } 52 | m.reBuildLocked() 53 | } 54 | 55 | func (m *ModHash) Add(ep endpoint.Endpoint) error { 56 | m.Lock() 57 | defer m.Unlock() 58 | if err := m.addLocked(ep); err != nil { 59 | return err 60 | } 61 | m.reBuildLocked() 62 | return nil 63 | } 64 | 65 | func (m *ModHash) addLocked(ep endpoint.Endpoint) error { 66 | if _, ok := m.mapValues[ep.HashKey()]; ok { 67 | return fmt.Errorf("modhash: endpoint %+v already exists", ep) 68 | } 69 | m.endpoints = append(m.endpoints, ep) 70 | m.mapValues[ep.HashKey()] = struct{}{} 71 | return nil 72 | } 73 | 74 | func (m *ModHash) Remove(ep endpoint.Endpoint) error { 75 | m.Lock() 76 | defer m.Unlock() 77 | if _, ok := m.mapValues[ep.HashKey()]; !ok { 78 | return fmt.Errorf("modhash: endpoint %+v already removed", ep) 79 | } 80 | delete(m.mapValues, ep.HashKey()) 81 | for i, n := range m.endpoints { 82 | if n.HashKey() == ep.HashKey() { 83 | m.endpoints = append(m.endpoints[:i], m.endpoints[i+1:]...) 84 | break 85 | } 86 | } 87 | m.reBuildLocked() 88 | return nil 89 | } 90 | 91 | func (m *ModHash) reBuildLocked() { 92 | m.staticWeightRouterCache = nil 93 | if m.enableWeight { 94 | m.staticWeightRouterCache = selector.BuildStaticWeightList(m.endpoints) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tars/selector/roundrobin/round_robin_test.go: -------------------------------------------------------------------------------- 1 | package roundrobin 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/util/endpoint" 7 | ) 8 | 9 | func TestRoundRobin(t *testing.T) { 10 | w := New(true) 11 | w.Add(endpoint.Parse("tcp -h 127.0.0.1 -p 19386 -t 60000 -v 1 -w 3")) 12 | w.Add(endpoint.Parse("tcp -h 127.0.0.2 -p 19387 -t 60000 -v 1 -w 3")) 13 | w.Add(endpoint.Parse("tcp -h 127.0.0.3 -p 19388 -t 60000 -v 1 -w 3")) 14 | w.Add(endpoint.Parse("tcp -h 127.0.0.4 -p 19388 -t 60000 -v 1 -w 3")) 15 | 16 | stats := map[string]int{} 17 | for i := 0; i < 80; i++ { 18 | point, _ := w.Select(nil) 19 | stats[point.Host]++ 20 | } 21 | t.Log(stats) 22 | 23 | w.Remove(endpoint.Parse("tcp -h 127.0.0.4 -p 19388 -t 60000 -v 1 -w 3")) 24 | 25 | stats = map[string]int{} 26 | for i := 0; i < 81; i++ { 27 | point, _ := w.Select(nil) 28 | stats[point.Host]++ 29 | } 30 | t.Log(stats) 31 | } 32 | -------------------------------------------------------------------------------- /tars/tools/pb2tarsgo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/tars/tools/pb2tarsgo 2 | 3 | go 1.14 4 | 5 | require github.com/golang/protobuf v1.3.5 6 | -------------------------------------------------------------------------------- /tars/tools/pb2tarsgo/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= 2 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 3 | -------------------------------------------------------------------------------- /tars/tools/pb2tarsgo/protoc-gen-go/link_tarsrpc.go: -------------------------------------------------------------------------------- 1 | // Go support for Protocol Buffers - Google's data interchange format 2 | // 3 | // Copyright 2015 The Go Authors. All rights reserved. 4 | // https://github.com/golang/protobuf 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions are 8 | // met: 9 | // 10 | // * Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // * Redistributions in binary form must reproduce the above 13 | // copyright notice, this list of conditions and the following disclaimer 14 | // in the documentation and/or other materials provided with the 15 | // distribution. 16 | // * Neither the name of Google Inc. nor the names of its 17 | // contributors may be used to endorse or promote products derived from 18 | // this software without specific prior written permission. 19 | // 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | package main 33 | 34 | import _ "github.com/TarsCloud/TarsGo/tars/tools/pb2tarsgo/protoc-gen-go/tarsrpc" 35 | -------------------------------------------------------------------------------- /tars/tools/protoc-gen-go-tarsrpc/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/tars/tools/protoc-gen-go-tarsrpc 2 | 3 | go 1.14 4 | 5 | require google.golang.org/protobuf v1.28.0 6 | -------------------------------------------------------------------------------- /tars/tools/protoc-gen-go-tarsrpc/go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 3 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 4 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 5 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 6 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 7 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 8 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 9 | -------------------------------------------------------------------------------- /tars/tools/protoc-gen-go-tarsrpc/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2022 tars authors. 4 | * 5 | * Licensed under the Apache License, version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | // protoc-gen-go-tarsrpc is a plugin for the Google protocol buffer compiler to 20 | // generate Go code. Install it by building this program and making it 21 | // accessible within your PATH with the name: 22 | // protoc-gen-go-tarsrpc 23 | // 24 | // The 'go-tarsrpc' suffix becomes part of the argument for the protocol compiler, 25 | // such that it can be invoked as: 26 | // protoc --go-tarsrpc_out=. path/to/file.proto 27 | // 28 | // This generates Go service definitions for the protocol buffer defined by 29 | // file.proto. With that input, the output will be written to: 30 | // path/to/file_tars.pb.go 31 | package main 32 | 33 | import ( 34 | "flag" 35 | "fmt" 36 | "google.golang.org/protobuf/compiler/protogen" 37 | "google.golang.org/protobuf/types/pluginpb" 38 | ) 39 | 40 | func main() { 41 | showVersion := flag.Bool("version", false, "print the version and exit") 42 | flag.Parse() 43 | if *showVersion { 44 | fmt.Printf("protoc-gen-go-tarsrpc %v\n", version) 45 | return 46 | } 47 | 48 | var flags flag.FlagSet 49 | protogen.Options{ 50 | ParamFunc: flags.Set, 51 | }.Run(func(gen *protogen.Plugin) error { 52 | gen.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) 53 | for _, f := range gen.Files { 54 | if !f.Generate { 55 | continue 56 | } 57 | GenerateFile(gen, f) 58 | } 59 | return nil 60 | }) 61 | } 62 | -------------------------------------------------------------------------------- /tars/tools/tars2go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/tars/tools/tars2go 2 | 3 | go 1.12 4 | -------------------------------------------------------------------------------- /tars/tools/tars2go/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // tars2go 3 | // 4 | 5 | package main 6 | 7 | import ( 8 | "flag" 9 | "os" 10 | 11 | "github.com/TarsCloud/TarsGo/tars/tools/tars2go/gencode" 12 | "github.com/TarsCloud/TarsGo/tars/tools/tars2go/options" 13 | ) 14 | 15 | func main() { 16 | opt := options.NewOptions() 17 | if flag.NArg() == 0 { 18 | opt.PrintHelp() 19 | os.Exit(0) 20 | } 21 | 22 | for _, filename := range flag.Args() { 23 | gen := gencode.NewGenGo(opt, filename) 24 | gen.Gen() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tars/tools/tars2go/options/options.go: -------------------------------------------------------------------------------- 1 | package options 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | type ImportPath []string 11 | 12 | type Options struct { 13 | Imports ImportPath 14 | TarsPath string 15 | Outdir string 16 | Module string 17 | Include string 18 | Includes []string 19 | 20 | WithoutTrace bool 21 | // gen 22 | E bool 23 | AddServant bool 24 | ModuleCycle bool 25 | ModuleUpper bool 26 | JsonOmitEmpty bool 27 | DispatchReporter bool 28 | Debug bool 29 | } 30 | 31 | func NewOptions() *Options { 32 | o := &Options{} 33 | o.initFlags() 34 | return o 35 | } 36 | 37 | func (o *Options) initFlags() { 38 | flag.Usage = o.PrintHelp 39 | flag.Var(&o.Imports, "I", "Specify a specific import path") 40 | flag.StringVar(&o.TarsPath, "tarsPath", "github.com/TarsCloud/TarsGo/tars", "Specify the tars source path.") 41 | flag.StringVar(&o.Outdir, "outdir", "", "which dir to put generated code") 42 | flag.StringVar(&o.Module, "module", "", "current go module path") 43 | flag.StringVar(&o.Include, "include", "", "set search path of tars protocol") 44 | flag.BoolVar(&o.WithoutTrace, "without-trace", false, "no call chain tracking logic required") 45 | 46 | // gen options 47 | flag.BoolVar(&o.E, "E", false, "Generate code before fmt for troubleshooting") 48 | flag.BoolVar(&o.AddServant, "add-servant", true, "Generate AddServant function") 49 | flag.BoolVar(&o.ModuleCycle, "module-cycle", false, "support jce module cycle include(do not support jce file cycle include)") 50 | flag.BoolVar(&o.ModuleUpper, "module-upper", false, "native module names are supported, otherwise the system will upper the first letter of the module name") 51 | flag.BoolVar(&o.JsonOmitEmpty, "json-omitempty", false, "Generate json omitempty support") 52 | flag.BoolVar(&o.DispatchReporter, "dispatch-reporter", false, "Dispatch reporter support") 53 | flag.BoolVar(&o.Debug, "debug", false, "enable debug mode") 54 | flag.Parse() 55 | 56 | o.Includes = strings.FieldsFunc(o.Include, func(r rune) bool { 57 | return r == ';' || r == ',' || r == ':' || r == ' ' 58 | }) 59 | } 60 | 61 | func (o *Options) PrintHelp() { 62 | bin := os.Args[0] 63 | if i := strings.LastIndex(bin, "/"); i != -1 { 64 | bin = bin[i+1:] 65 | } 66 | fmt.Printf("Usage: %s [flags] *.tars\n", bin) 67 | fmt.Printf(" %s -I tars/protocol/res/endpoint [-I ...] QueryF.tars\n", bin) 68 | fmt.Printf(" %s -include=\"dir1;dir2;dir3\"\n", bin) 69 | flag.PrintDefaults() 70 | } 71 | 72 | func (ip *ImportPath) String() string { 73 | return strings.Join(*ip, ":") 74 | } 75 | 76 | func (ip *ImportPath) Set(value string) error { 77 | *ip = append(*ip, value) 78 | return nil 79 | } 80 | -------------------------------------------------------------------------------- /tars/tools/tars2go/utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "strings" 4 | 5 | // UpperFirstLetter Initial capitalization 6 | func UpperFirstLetter(s string) string { 7 | if len(s) == 0 { 8 | return "" 9 | } 10 | if len(s) == 1 { 11 | return strings.ToUpper(string(s[0])) 12 | } 13 | return strings.ToUpper(string(s[0])) + s[1:] 14 | } 15 | 16 | func Path2ProtoName(path string) string { 17 | iBegin := strings.LastIndex(path, "/") 18 | if iBegin == -1 || iBegin >= len(path)-1 { 19 | iBegin = 0 20 | } else { 21 | iBegin++ 22 | } 23 | iEnd := strings.LastIndex(path, ".tars") 24 | if iEnd == -1 { 25 | iEnd = len(path) 26 | } 27 | 28 | return path[iBegin:iEnd] 29 | } 30 | -------------------------------------------------------------------------------- /tars/tools/tars2go/version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | // VERSION of the tars2go tools. 4 | const VERSION = "1.2.4" 5 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/.gitignore: -------------------------------------------------------------------------------- 1 | !go.sum 2 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TarsCloud/TarsGo/tars/tools/tarsgo 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/AlecAivazis/survey/v2 v2.2.15 7 | github.com/fatih/color v1.13.0 8 | github.com/mitchellh/go-homedir v1.1.0 9 | github.com/spf13/cobra v1.3.0 10 | golang.org/x/mod v0.5.0 11 | golang.org/x/sys v0.1.0 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/base/args.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "fmt" 5 | "github.com/AlecAivazis/survey/v2" 6 | "github.com/spf13/cobra" 7 | "strings" 8 | ) 9 | 10 | func GetArgs(cmd *cobra.Command, args []string) (app, server, servant, goModuleName string, err error) { 11 | if len(args) == 0 { 12 | prompt := &survey.Input{ 13 | Message: "What is project app ?", 14 | Help: "Created project app.", 15 | } 16 | err = survey.AskOne(prompt, &app) 17 | if err != nil || app == "" { 18 | return 19 | } 20 | prompt = &survey.Input{ 21 | Message: "What is project server ?", 22 | Help: "Created project server.", 23 | } 24 | err = survey.AskOne(prompt, &server) 25 | if err != nil || server == "" { 26 | return 27 | } 28 | prompt = &survey.Input{ 29 | Message: "What is project servant ?", 30 | Help: "Created project servant.", 31 | } 32 | err = survey.AskOne(prompt, &servant) 33 | if err != nil || servant == "" { 34 | return 35 | } 36 | prompt = &survey.Input{ 37 | Message: "What is project GoModuleName ?", 38 | Help: "Created project GoModuleName.", 39 | } 40 | err = survey.AskOne(prompt, &goModuleName) 41 | if err != nil || goModuleName == "" { 42 | return 43 | } 44 | } else if len(args) != 4 { 45 | _ = cmd.Help() 46 | err = fmt.Errorf("args: %+v", args) 47 | return 48 | } else { 49 | app = args[0] 50 | server = args[1] 51 | servant = args[2] 52 | goModuleName = args[3] 53 | } 54 | return app, server, servant, goModuleName, nil 55 | } 56 | 57 | // FirstUpper 字符串首字母大写 58 | func FirstUpper(s string) string { 59 | if s == "" { 60 | return "" 61 | } 62 | return strings.ToUpper(s[:1]) + s[1:] 63 | } 64 | 65 | // FirstLower 字符串首字母小写 66 | func FirstLower(s string) string { 67 | if s == "" { 68 | return "" 69 | } 70 | return strings.ToLower(s[:1]) + s[1:] 71 | } 72 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/base/install.go: -------------------------------------------------------------------------------- 1 | //go:build go1.17 2 | // +build go1.17 3 | 4 | package base 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "strings" 11 | ) 12 | 13 | // GoInstall go get path. 14 | func GoInstall(path ...string) error { 15 | for _, p := range path { 16 | if !strings.Contains(p, "@") { 17 | p += "@latest" 18 | } 19 | fmt.Printf("go install %s\n", p) 20 | cmd := exec.Command("go", "install", p) 21 | cmd.Stdout = os.Stdout 22 | cmd.Stderr = os.Stderr 23 | if err := cmd.Run(); err != nil { 24 | return err 25 | } 26 | } 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/base/install_compatible.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.17 2 | // +build !go1.17 3 | 4 | package base 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | ) 11 | 12 | // GoInstall go get path. 13 | func GoInstall(path ...string) error { 14 | for _, p := range path { 15 | fmt.Printf("go get -u %s\n", p) 16 | cmd := exec.Command("go", "get", "-u", p) 17 | cmd.Stdout = os.Stdout 18 | cmd.Stderr = os.Stderr 19 | if err := cmd.Run(); err != nil { 20 | return err 21 | } 22 | } 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/base/mod.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | "strings" 10 | 11 | "golang.org/x/mod/modfile" 12 | ) 13 | 14 | // ModulePath returns go module path. 15 | func ModulePath(filename string) (string, error) { 16 | modBytes, err := os.ReadFile(filename) 17 | if err != nil { 18 | return "", err 19 | } 20 | return modfile.ModulePath(modBytes), nil 21 | } 22 | 23 | // ModuleVersion returns module version. 24 | func ModuleVersion(path string) (string, error) { 25 | stdout := &bytes.Buffer{} 26 | fd := exec.Command("go", "mod", "graph") 27 | fd.Stdout = stdout 28 | fd.Stderr = stdout 29 | if err := fd.Run(); err != nil { 30 | return "", err 31 | } 32 | rd := bufio.NewReader(stdout) 33 | for { 34 | line, _, err := rd.ReadLine() 35 | if err != nil { 36 | return "", err 37 | } 38 | str := string(line) 39 | i := strings.Index(str, "@") 40 | if strings.Contains(str, path+"@") && i != -1 { 41 | return path + str[i:], nil 42 | } 43 | } 44 | } 45 | 46 | // TarsGoMod returns TarsGo mod. 47 | func TarsGoMod() string { 48 | // go 1.15+ read from env GOMODCACHE 49 | cacheOut, _ := exec.Command("go", "env", "GOMODCACHE").Output() 50 | cachePath := strings.Trim(string(cacheOut), "\n") 51 | pathOut, _ := exec.Command("go", "env", "GOPATH").Output() 52 | gopath := strings.Trim(string(pathOut), "\n") 53 | if cachePath == "" { 54 | cachePath = filepath.Join(gopath, "pkg", "mod") 55 | } 56 | if path, err := ModuleVersion("github.com/TarsCloud/TarsGo"); err == nil { 57 | // $GOPATH/pkg/mod/github.com/TarsCloud/TarsGo@v1.1.4 58 | return filepath.Join(cachePath, path) 59 | } 60 | // $GOPATH/src/github.com/TarsCloud/TarsGo 61 | return filepath.Join(gopath, "src", "github.com", "TarsCloud", "TarsGo") 62 | } 63 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/base/mod_test.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import "testing" 4 | 5 | func TestModuleVersion(t *testing.T) { 6 | v, err := ModuleVersion("golang.org/x/mod") 7 | if err != nil { 8 | t.Fatal(err) 9 | } 10 | t.Log(v) 11 | } 12 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/base/repo_test.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | ) 7 | 8 | func TestRepo(t *testing.T) { 9 | r := NewRepo("https://github.com/TarsCloud/TarsGo.git", "", "") 10 | if err := r.CopyTo(context.Background(), &Project{ 11 | App: "DemoApp", 12 | Server: "DemoServer", 13 | Servant: "DemoServant", 14 | GoModuleName: "demo", 15 | }, "github.com/TarsCloud/TarsGo", "", []string{}); err != nil { 16 | t.Fatal(err) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/cmake/cmake.go: -------------------------------------------------------------------------------- 1 | package cmake 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/base" 8 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/consts" 9 | "os" 10 | "time" 11 | 12 | "github.com/fatih/color" 13 | "github.com/spf13/cobra" 14 | ) 15 | 16 | // CmdNew represents the new command. 17 | var CmdNew = &cobra.Command{ 18 | Use: "cmake App Server Servant GoModuleName", 19 | Short: "Create a service cmake template", 20 | Long: `Create a service cmake project using the repository template. Example: 21 | tarsgo cmake Hello HelloServer HelloWorld github.com/Hello/HelloServer`, 22 | Run: run, 23 | } 24 | 25 | var ( 26 | repoUrl string 27 | branch string 28 | timeout string 29 | ) 30 | 31 | func init() { 32 | timeout = "60s" 33 | CmdNew.Flags().StringVarP(&repoUrl, "repo-url", "r", consts.RepoURL, "layout repo") 34 | CmdNew.Flags().StringVarP(&branch, "branch", "b", branch, "repo branch") 35 | CmdNew.Flags().StringVarP(&timeout, "timeout", "t", timeout, "time out") 36 | } 37 | 38 | func run(cmd *cobra.Command, args []string) { 39 | wd, err := os.Getwd() 40 | if err != nil { 41 | panic(err) 42 | } 43 | t, err := time.ParseDuration(timeout) 44 | if err != nil { 45 | panic(err) 46 | } 47 | app, server, servant, goModuleName, err := base.GetArgs(cmd, args) 48 | if err != nil { 49 | return 50 | } 51 | p := base.NewProject(app, server, servant, goModuleName) 52 | ctx, cancel := context.WithTimeout(context.Background(), t) 53 | defer cancel() 54 | done := make(chan error, 1) 55 | go func() { 56 | done <- p.Create(ctx, wd, consts.CMake) 57 | }() 58 | select { 59 | case <-ctx.Done(): 60 | if errors.Is(ctx.Err(), context.DeadlineExceeded) { 61 | fmt.Fprint(os.Stderr, color.RedString("ERROR: project creation timed out\n")) 62 | } else { 63 | fmt.Fprintf(os.Stderr, color.RedString("ERROR: failed to create project(%+v)\n", ctx.Err().Error())) 64 | } 65 | case err = <-done: 66 | if err != nil { 67 | fmt.Fprintf(os.Stderr, color.RedString("ERROR: Failed to create project(%+v)\n", err.Error())) 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/consts/makefile.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | IncludeMakefile = "scripts/makefile.tars.gomod.mk" 5 | ) 6 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/consts/version.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | // Release is the current tarsgo tool version. 4 | const ( 5 | RepoURL = "https://github.com/TarsCloud/TarsGo.git" 6 | Release = "v1.3.6" 7 | MakeDemoDir = "Demo4GoMod" 8 | //CMakeDemoDir = "Demo4Cmake" 9 | Make = "make" 10 | CMake = "cmake" 11 | ) 12 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/make/make.go: -------------------------------------------------------------------------------- 1 | package make 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/base" 8 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/consts" 9 | "github.com/fatih/color" 10 | "os" 11 | "time" 12 | 13 | "github.com/spf13/cobra" 14 | ) 15 | 16 | // CmdNew represents the new command. 17 | var CmdNew = &cobra.Command{ 18 | Use: "make App Server Servant GoModuleName", 19 | Short: "Create a server make template", 20 | Long: `Create a server make project using the repository template. Example: 21 | tarsgo make TestApp HelloGo Hello github.com/TestApp/HelloGo`, 22 | Run: run, 23 | } 24 | 25 | var ( 26 | repoUrl string 27 | branch string 28 | timeout string 29 | ) 30 | 31 | func init() { 32 | timeout = "60s" 33 | CmdNew.Flags().StringVarP(&repoUrl, "repo-url", "r", consts.RepoURL, "layout repo") 34 | CmdNew.Flags().StringVarP(&branch, "branch", "b", branch, "repo branch") 35 | CmdNew.Flags().StringVarP(&timeout, "timeout", "t", timeout, "time out") 36 | } 37 | 38 | func run(cmd *cobra.Command, args []string) { 39 | wd, err := os.Getwd() 40 | if err != nil { 41 | panic(err) 42 | } 43 | t, err := time.ParseDuration(timeout) 44 | if err != nil { 45 | panic(err) 46 | } 47 | app, server, servant, goModuleName, err := base.GetArgs(cmd, args) 48 | if err != nil { 49 | return 50 | } 51 | p := base.NewProject(app, server, servant, goModuleName) 52 | done := make(chan error, 1) 53 | ctx, cancel := context.WithTimeout(context.Background(), t) 54 | defer cancel() 55 | go func() { 56 | done <- p.Create(ctx, wd, consts.Make) 57 | }() 58 | select { 59 | case <-ctx.Done(): 60 | if errors.Is(ctx.Err(), context.DeadlineExceeded) { 61 | fmt.Fprint(os.Stderr, color.RedString("ERROR: project creation timed out\n")) 62 | } else { 63 | fmt.Fprintf(os.Stderr, color.RedString("ERROR: failed to create project(%+v)\n", ctx.Err().Error())) 64 | } 65 | case err = <-done: 66 | if err != nil { 67 | fmt.Fprintf(os.Stderr, color.RedString("ERROR: Failed to create project(%+v)\n", err.Error())) 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/upgrade/cmake.go: -------------------------------------------------------------------------------- 1 | package upgrade 2 | 3 | import ( 4 | "fmt" 5 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/base" 6 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/bindata" 7 | "github.com/fatih/color" 8 | "github.com/spf13/cobra" 9 | "os" 10 | "path" 11 | ) 12 | 13 | // CmakeCmd represents the new command. 14 | var CmakeCmd = &cobra.Command{ 15 | Use: "cmake", 16 | Short: "Auto upgrade CMakeLists.txt", 17 | Long: `Auto upgrade CMakeLists.txt. Example: 18 | tarsgo upgrade cmake`, 19 | Run: func(cmd *cobra.Command, args []string) { 20 | wd, err := os.Getwd() 21 | if err != nil { 22 | panic(err) 23 | } 24 | cmakeListsTxt := path.Join(wd, "CMakeLists.txt") 25 | err = base.CopyFile(cmakeListsTxt, cmakeListsTxt, []string{ 26 | "${GOPATH}/src/github.com/TarsCloud/TarsGo/", "${CMAKE_CURRENT_SOURCE_DIR}/", 27 | }) 28 | if err != nil { 29 | panic(err) 30 | } 31 | err = bindata.RestoreAssets(wd, "cmake") 32 | if err != nil { 33 | panic(err) 34 | } 35 | fmt.Println(color.GreenString("upgrade success")) 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/upgrade/make.go: -------------------------------------------------------------------------------- 1 | package upgrade 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path" 7 | 8 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/base" 9 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/bindata" 10 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/consts" 11 | "github.com/fatih/color" 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | // MakeCmd represents the new command. 16 | var MakeCmd = &cobra.Command{ 17 | Use: "make", 18 | Short: "Auto upgrade makefile", 19 | Long: `Auto upgrade makefile. Example: 20 | tarsgo upgrade make`, 21 | Run: func(cmd *cobra.Command, args []string) { 22 | wd, err := os.Getwd() 23 | if err != nil { 24 | panic(err) 25 | } 26 | makefile := path.Join(wd, "makefile") 27 | err = base.CopyFile(makefile, makefile, []string{ 28 | ` 29 | libpath=${subst :, ,$(GOPATH)}`, "", 30 | "$(foreach path,$(libpath),$(eval -include $(path)/src/github.com/TarsCloud/TarsGo/tars/makefile.tars))", "-include " + consts.IncludeMakefile, 31 | "$(foreach path,$(libpath),$(eval -include $(path)/src/github.com/TarsCloud/TarsGo/tars/makefile.tars.gomod))", "-include " + consts.IncludeMakefile, 32 | }) 33 | if err != nil { 34 | panic(err) 35 | } 36 | err = bindata.RestoreAsset(wd, consts.IncludeMakefile) 37 | if err != nil { 38 | panic(err) 39 | } 40 | fmt.Println(color.GreenString("upgrade success")) 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/internal/upgrade/upgrade.go: -------------------------------------------------------------------------------- 1 | package upgrade 2 | 3 | import ( 4 | "fmt" 5 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/base" 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | // CmdNew UpgradeCmd represents the new command. 10 | var CmdNew = &cobra.Command{ 11 | Use: "upgrade", 12 | Short: "Auto upgrade tarsgo and tars2go", 13 | Long: `Auto upgrade tarsgo and tars2go. Example: 14 | tarsgo upgrade`, 15 | Run: run, 16 | } 17 | 18 | var force bool 19 | 20 | func init() { 21 | CmdNew.Flags().BoolVarP(&force, "force", "f", false, "force upgrade tarsgo and tars2go") 22 | CmdNew.AddCommand(MakeCmd) 23 | CmdNew.AddCommand(CmakeCmd) 24 | } 25 | 26 | func run(cmd *cobra.Command, args []string) { 27 | if force { 28 | err := base.GoInstall( 29 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo", 30 | "github.com/TarsCloud/TarsGo/tars/tools/tars2go", 31 | //"github.com/TarsCloud/TarsGo/tars/tools/protoc-gen-go", 32 | "google.golang.org/protobuf/cmd/protoc-gen-go", 33 | "github.com/TarsCloud/TarsGo/tars/tools/protoc-gen-go-tarsrpc", 34 | ) 35 | if err != nil { 36 | fmt.Println(err) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tars/tools/tarsgo/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 NAME HERE 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package main 17 | 18 | import ( 19 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/cmake" 20 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/consts" 21 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/make" 22 | "github.com/TarsCloud/TarsGo/tars/tools/tarsgo/internal/upgrade" 23 | "github.com/spf13/cobra" 24 | "log" 25 | ) 26 | 27 | var rootCmd = &cobra.Command{ 28 | Use: "tarsgo", 29 | Short: "tarsgo: An elegant toolkit for Go microservices.", 30 | Long: `tarsgo: An elegant toolkit for Go microservices.`, 31 | Version: consts.Release, 32 | } 33 | 34 | func init() { 35 | rootCmd.AddCommand(make.CmdNew) 36 | rootCmd.AddCommand(cmake.CmdNew) 37 | rootCmd.AddCommand(upgrade.CmdNew) 38 | } 39 | 40 | func main() { 41 | if err := rootCmd.Execute(); err != nil { 42 | log.Fatal(err) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tars/transport.go: -------------------------------------------------------------------------------- 1 | package tars 2 | 3 | import ( 4 | "crypto/tls" 5 | 6 | "github.com/TarsCloud/TarsGo/tars/transport" 7 | ) 8 | 9 | type ServerConfOption func(*transport.TarsServerConf) 10 | 11 | func WithQueueCap(queueCap int) ServerConfOption { 12 | return func(c *transport.TarsServerConf) { 13 | c.QueueCap = queueCap 14 | } 15 | } 16 | 17 | func WithTlsConfig(tlsConfig *tls.Config) ServerConfOption { 18 | return func(c *transport.TarsServerConf) { 19 | c.TlsConfig = tlsConfig 20 | } 21 | } 22 | 23 | func WithMaxInvoke(maxInvoke int32) ServerConfOption { 24 | return func(c *transport.TarsServerConf) { 25 | c.MaxInvoke = maxInvoke 26 | } 27 | } 28 | 29 | func newTarsServerConf(proto, address string, svrCfg *serverConfig, opts ...ServerConfOption) *transport.TarsServerConf { 30 | tarsSvrConf := &transport.TarsServerConf{ 31 | Proto: proto, 32 | Address: address, 33 | MaxInvoke: svrCfg.MaxInvoke, 34 | AcceptTimeout: svrCfg.AcceptTimeout, 35 | ReadTimeout: svrCfg.ReadTimeout, 36 | WriteTimeout: svrCfg.WriteTimeout, 37 | HandleTimeout: svrCfg.HandleTimeout, 38 | IdleTimeout: svrCfg.IdleTimeout, 39 | QueueCap: svrCfg.QueueCap, 40 | TCPNoDelay: svrCfg.TCPNoDelay, 41 | TCPReadBuffer: svrCfg.TCPReadBuffer, 42 | TCPWriteBuffer: svrCfg.TCPWriteBuffer, 43 | } 44 | for _, opt := range opts { 45 | opt(tarsSvrConf) 46 | } 47 | return tarsSvrConf 48 | } 49 | -------------------------------------------------------------------------------- /tars/transport/_examples/helloserver/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "strconv" 7 | "time" 8 | 9 | "github.com/TarsCloud/TarsGo/tars/transport" 10 | ) 11 | 12 | // MyClient is a example client for tars client testing. 13 | type MyClient struct { 14 | recvCount int 15 | } 16 | 17 | // Recv print pkg and count 18 | func (c *MyClient) Recv(pkg []byte) { 19 | fmt.Println("recv", string(pkg)) 20 | c.recvCount++ 21 | } 22 | 23 | // ParsePackage parse package from buff 24 | func (c *MyClient) ParsePackage(buff []byte) (pkgLen, status int) { 25 | if len(buff) < 4 { 26 | return 0, transport.PackageLess 27 | } 28 | length := binary.BigEndian.Uint32(buff[:4]) 29 | 30 | if length > 1048576000 || len(buff) > 1048576000 { // 1000MB 31 | return 0, transport.PackageError 32 | } 33 | if len(buff) < int(length) { 34 | return 0, transport.PackageLess 35 | } 36 | return int(length), transport.PackageFull 37 | } 38 | 39 | func getMsg(name string) []byte { 40 | payload := []byte(name) 41 | pkg := make([]byte, 4+len(payload)) 42 | binary.BigEndian.PutUint32(pkg[:4], uint32(len(pkg))) 43 | copy(pkg[4:], payload) 44 | return pkg 45 | } 46 | 47 | func main() { 48 | cp := &MyClient{} 49 | conf := &transport.TarsClientConf{ 50 | Proto: "tcp", 51 | QueueLen: 10000, 52 | IdleTimeout: time.Second * 5, 53 | ReadTimeout: time.Millisecond * 100, 54 | WriteTimeout: time.Millisecond * 1000, 55 | } 56 | client := transport.NewTarsClient("localhost:3333", cp, conf) 57 | 58 | name := "Bob" 59 | count := 500 60 | for i := 0; i < count; i++ { 61 | msg := getMsg(name + strconv.Itoa(i)) 62 | if err := client.Send(msg); err != nil { 63 | fmt.Println("send err: " + err.Error()) 64 | } 65 | } 66 | 67 | time.Sleep(time.Second * 1) 68 | if count != cp.recvCount { 69 | fmt.Println("bad") 70 | } else { 71 | fmt.Println("good") 72 | } 73 | client.Close() 74 | } 75 | -------------------------------------------------------------------------------- /tars/transport/_examples/helloserver/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/binary" 6 | "fmt" 7 | "time" 8 | 9 | "github.com/TarsCloud/TarsGo/tars/transport" 10 | ) 11 | 12 | // MyServer struct for testing tars tcp server 13 | type MyServer struct{} 14 | 15 | func (s *MyServer) GetCloseMsg() []byte { 16 | return []byte("") 17 | } 18 | 19 | func (s *MyServer) DoClose(ctx context.Context) { 20 | } 21 | 22 | // Invoke recv request and make response. 23 | func (s *MyServer) Invoke(ctx context.Context, req []byte) (rsp []byte) { 24 | fmt.Println("recv", string(req)) 25 | rsp = make([]byte, 4) 26 | rsp = append(rsp, []byte("Hello ")...) 27 | rsp = append(rsp, req[4:]...) 28 | binary.BigEndian.PutUint32(rsp[:4], uint32(len(rsp))) 29 | return 30 | } 31 | 32 | // ParsePackage parse package from buff,check if tars package finished. 33 | func (s *MyServer) ParsePackage(buff []byte) (pkgLen, status int) { 34 | if len(buff) < 4 { 35 | return 0, transport.PackageLess 36 | } 37 | length := binary.BigEndian.Uint32(buff[:4]) 38 | 39 | if length > 1048576000 || len(buff) > 1048576000 { // 1000MB 40 | return 0, transport.PackageError 41 | } 42 | if len(buff) < int(length) { 43 | return 0, transport.PackageLess 44 | } 45 | return int(length), transport.PackageFull 46 | } 47 | 48 | // InvokeTimeout how to detail with timeout package. 49 | func (s *MyServer) InvokeTimeout(pkg []byte) []byte { 50 | payload := []byte("timeout") 51 | ret := make([]byte, 4+len(payload)) 52 | binary.BigEndian.PutUint32(pkg[:4], uint32(len(ret))) 53 | copy(pkg[4:], payload) 54 | return ret 55 | } 56 | 57 | func main() { 58 | conf := &transport.TarsServerConf{ 59 | Proto: "tcp", 60 | Address: "localhost:3333", 61 | MaxInvoke: 20, 62 | AcceptTimeout: time.Millisecond * 500, 63 | ReadTimeout: time.Millisecond * 100, 64 | WriteTimeout: time.Millisecond * 100, 65 | HandleTimeout: time.Millisecond * 6000, 66 | IdleTimeout: time.Millisecond * 600000, 67 | } 68 | s := MyServer{} 69 | svr := transport.NewTarsServer(&s, conf) 70 | if err := svr.Listen(); err != nil { 71 | panic(err) 72 | } 73 | if err := svr.Serve(); err != nil { 74 | panic(err) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tars/transport/_examples/udpserver/client.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strconv" 9 | ) 10 | 11 | func hello(conn net.Conn, name string) { 12 | payload := []byte(name) 13 | pkg := make([]byte, 4+len(payload)) 14 | binary.BigEndian.PutUint32(pkg[:4], uint32(len(pkg))) 15 | copy(pkg[4:], payload) 16 | conn.Write(pkg) 17 | buf := make([]byte, 1024*4) 18 | n, err := conn.Read(buf) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | fmt.Println(string(buf[4:n])) 24 | } 25 | 26 | func main() { 27 | name := "Bob" 28 | if len(os.Args) == 2 { 29 | name = os.Args[1] 30 | } 31 | addr, err := net.ResolveUDPAddr("udp", "localhost:3333") 32 | if err != nil { 33 | fmt.Println("Can't resolve address: ", err) 34 | os.Exit(1) 35 | } 36 | conn, err := net.DialUDP("udp", nil, addr) 37 | if err != nil { 38 | fmt.Println("Can't dial: ", err) 39 | os.Exit(1) 40 | } 41 | 42 | defer conn.Close() 43 | for i := 0; i < 5; i++ { 44 | hello(conn, name+strconv.Itoa(i)) 45 | } 46 | 47 | os.Exit(0) 48 | } 49 | -------------------------------------------------------------------------------- /tars/transport/_examples/udpserver/server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/binary" 6 | "fmt" 7 | "time" 8 | 9 | "github.com/TarsCloud/TarsGo/tars/transport" 10 | ) 11 | 12 | // MyServer testing tars udp server 13 | type MyServer struct{} 14 | 15 | func (s *MyServer) GetCloseMsg() []byte { 16 | return []byte("") 17 | } 18 | 19 | func (s *MyServer) DoClose(ctx context.Context) { 20 | } 21 | 22 | // Invoke recv package and make response. 23 | func (s *MyServer) Invoke(ctx context.Context, req []byte) (rsp []byte) { 24 | rsp = make([]byte, 4) 25 | rsp = append(rsp, []byte("Hello ")...) 26 | rsp = append(rsp, req[4:]...) 27 | binary.BigEndian.PutUint32(rsp[:4], uint32(len(rsp))) 28 | return 29 | } 30 | 31 | // ParsePackage parse full tars package. 32 | func (s *MyServer) ParsePackage(buff []byte) (pkgLen, status int) { 33 | if len(buff) < 4 { 34 | return 0, transport.PackageLess 35 | } 36 | length := binary.BigEndian.Uint32(buff[:4]) 37 | 38 | if length > 1048576000 || len(buff) > 1048576000 { // 1000MB 39 | return 0, transport.PackageError 40 | } 41 | if len(buff) < int(length) { 42 | return 0, transport.PackageLess 43 | } 44 | return int(length), transport.PackageFull 45 | } 46 | 47 | // InvokeTimeout show how to deal with timeout response. 48 | func (s *MyServer) InvokeTimeout(pkg []byte) []byte { 49 | payload := []byte("timeout") 50 | ret := make([]byte, 4+len(payload)) 51 | binary.BigEndian.PutUint32(pkg[:4], uint32(len(ret))) 52 | copy(pkg[4:], payload) 53 | return ret 54 | } 55 | 56 | func main() { 57 | conf := &transport.TarsServerConf{ 58 | Proto: "udp", 59 | Address: "127.0.0.1:3333", 60 | MaxInvoke: 20, 61 | AcceptTimeout: time.Millisecond * 500, 62 | ReadTimeout: time.Millisecond * 100, 63 | WriteTimeout: time.Millisecond * 100, 64 | HandleTimeout: time.Millisecond * 6000, 65 | IdleTimeout: time.Millisecond * 600000, 66 | } 67 | s := MyServer{} 68 | svr := transport.NewTarsServer(&s, conf) 69 | if err := svr.Listen(); err != nil { 70 | panic(err) 71 | } 72 | if err := svr.Serve(); err != nil { 73 | fmt.Println(err) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tars/transport/common.go: -------------------------------------------------------------------------------- 1 | package transport 2 | 3 | import ( 4 | "context" 5 | "net" 6 | ) 7 | 8 | const ( 9 | // PackageLess shows is not a completed package. 10 | PackageLess = iota 11 | // PackageFull shows is a completed package. 12 | PackageFull 13 | // PackageError shows is a error package. 14 | PackageError 15 | ) 16 | 17 | // ServerHandler is interface with listen and handler method 18 | type ServerHandler interface { 19 | Listen() error 20 | Handle() error 21 | OnShutdown() 22 | CloseIdles(n int64) bool 23 | } 24 | 25 | // ServerProtocol is interface for handling the server side tars package. 26 | type ServerProtocol interface { 27 | Invoke(ctx context.Context, pkg []byte) []byte 28 | ParsePackage(buff []byte) (int, int) 29 | InvokeTimeout(pkg []byte) []byte 30 | GetCloseMsg() []byte 31 | DoClose(ctx context.Context) 32 | } 33 | 34 | // ClientProtocol interface for handling tars client package. 35 | type ClientProtocol interface { 36 | Recv(pkg []byte) 37 | ParsePackage(buff []byte) (int, int) 38 | } 39 | 40 | func isNoDataError(err error) bool { 41 | netErr, ok := err.(net.Error) 42 | if ok && netErr.Timeout() && netErr.Temporary() { 43 | return true 44 | } 45 | return false 46 | } 47 | -------------------------------------------------------------------------------- /tars/util/conf/conf_test.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestConf(t *testing.T) { 9 | f1, _ := NewConf("MMGR.TestServer.conf") 10 | d := f1.GetDomain("/taf/application/server") 11 | fmt.Println(d) 12 | d1 := f1.GetDomainLine("/taf/nodes") 13 | fmt.Println(d1) 14 | d2 := f1.GetString("/taf/application/server") 15 | fmt.Println(d2) 16 | d3 := f1.GetString("/taf/application/client/") 17 | fmt.Println(d3) 18 | d4 := f1.GetInt("/taf/application/client") 19 | fmt.Println(d4) 20 | d5 := f1.GetMap("/taf/application/server/") 21 | fmt.Println(d5) 22 | fmt.Println(d5["node"]) 23 | d6 := f1.GetDomainKey("/taf/application/server") 24 | fmt.Println(d6) 25 | fmt.Println(f1.ToString()) 26 | } 27 | -------------------------------------------------------------------------------- /tars/util/debug/debugtool.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "path/filepath" 8 | "runtime" 9 | "time" 10 | ) 11 | 12 | // write2File write byte array to file 13 | // logname: prefix of the file's name, which is like logname.20060102-150405, and the file 14 | // will locates in the same diretory as the bin file which calls it 15 | // buf: call stack info 16 | func write2File(logname string, desc string, buf []byte) error { 17 | path, _ := filepath.Abs(filepath.Dir(os.Args[0])) 18 | os.Chdir(path) 19 | logpath := fmt.Sprintf("%s.%s", logname, time.Now().Format("20060102-150405")) 20 | 21 | var err error 22 | var file *os.File 23 | if file, err = os.OpenFile(logpath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644); err == nil { 24 | defer file.Close() 25 | if desc != "" { 26 | file.WriteString(desc + "\n\n") 27 | } 28 | file.WriteString(fmt.Sprintf("current running goroutine num: %d\n\n", runtime.NumGoroutine())) 29 | file.WriteString(string(buf)) 30 | fmt.Println("successfully dump stack info into file") 31 | } 32 | return err 33 | } 34 | 35 | // DumpStack used to dump stack info to file 36 | // all: true means dumping all running goroutine stack, else only dumping the one that calls the func 37 | // logname: prefix of the file's name, which is like logname.20060102-150405 38 | // msg: description message 39 | func DumpStack(all bool, logname string, desc string) { 40 | buf := make([]byte, 1024) 41 | for { 42 | //the buf is no more than 64M, because Stack dumps no more than 64M 43 | n := runtime.Stack(buf, all) 44 | if n < len(buf) { 45 | buf = buf[:n] //trim unreadable characters 46 | break 47 | } 48 | buf = make([]byte, 2*len(buf)) 49 | } 50 | write2File(logname, desc, buf) 51 | } 52 | 53 | // SigNotifyStack register os signals to be notified when to dumpstack 54 | // For example, SigNotifyStack(SIGUSR1, true, "stackinfo"), can dump all goroutine stack 55 | // when received SIGUSR1 signal by "kill -USR1 pid" 56 | // sig: self defined os signals, like SIGUSR1 SIGUSR2 in linux and darwin but not supoorted in windows 57 | // all: true means dumping all running goroutine stack, else only dumping the one that calls the func 58 | // logname: prefix of the file's name, which is like logname.20060102-150405 59 | func SigNotifyStack(sig os.Signal, all bool, logname string) { 60 | buf := make([]byte, 1024) 61 | c := make(chan os.Signal, 1) 62 | signal.Notify(c, sig) 63 | 64 | go func() { 65 | for range c { 66 | for { 67 | //the buf is no more than 64M, because Stack dumps no more than 64M 68 | n := runtime.Stack(buf, all) 69 | if n < len(buf) { 70 | buf = buf[:n] //trim unreadable characters 71 | break 72 | } 73 | buf = make([]byte, 2*len(buf)) 74 | } 75 | write2File(logname, "", buf) 76 | } 77 | }() 78 | } 79 | -------------------------------------------------------------------------------- /tars/util/debug/debugtool_test.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDumpStack(t *testing.T) { 8 | DumpStack(true, "testdump", "testdump") 9 | } 10 | -------------------------------------------------------------------------------- /tars/util/endpoint/convert.go: -------------------------------------------------------------------------------- 1 | package endpoint 2 | 3 | import "github.com/TarsCloud/TarsGo/tars/protocol/res/endpointf" 4 | 5 | // Tars2endpoint make endpointf.EndpointF to Endpoint struct. 6 | func Tars2endpoint(end endpointf.EndpointF) Endpoint { 7 | proto := "tcp" 8 | if end.Istcp == UDP { 9 | proto = "udp" 10 | } 11 | e := Endpoint{ 12 | Host: end.Host, 13 | Port: end.Port, 14 | Timeout: end.Timeout, 15 | Istcp: end.Istcp, 16 | Grid: end.Grid, 17 | Qos: end.Qos, 18 | Weight: end.Weight, 19 | WeightType: end.WeightType, 20 | AuthType: end.AuthType, 21 | Proto: proto, 22 | Bind: "", 23 | //Container: end.ContainerName, 24 | SetId: end.SetId, 25 | } 26 | e.Key = e.String() 27 | return e 28 | } 29 | 30 | // Endpoint2tars transfer Endpoint to endpointf.EndpointF 31 | func Endpoint2tars(end Endpoint) endpointf.EndpointF { 32 | return endpointf.EndpointF{ 33 | Host: end.Host, 34 | Port: end.Port, 35 | Timeout: end.Timeout, 36 | Istcp: end.Istcp, 37 | Grid: end.Grid, 38 | Qos: end.Qos, 39 | Weight: end.Weight, 40 | WeightType: end.WeightType, 41 | AuthType: end.AuthType, 42 | //ContainerName: end.Container, 43 | SetId: end.SetId, 44 | } 45 | } 46 | 47 | func IsEqual(a, b *[]endpointf.EndpointF) bool { 48 | if a == nil && b == nil { 49 | return true 50 | } 51 | if a == nil || b == nil || len(*a) != len(*b) { 52 | return false 53 | } 54 | for i, x := range *a { 55 | y := (*b)[i] 56 | if x.Host != y.Host || x.Port != y.Port || x.Istcp != y.Istcp || x.WeightType != y.WeightType || x.Weight != y.Weight { 57 | return false 58 | } 59 | } 60 | return true 61 | } 62 | -------------------------------------------------------------------------------- /tars/util/endpoint/endpoint.go: -------------------------------------------------------------------------------- 1 | package endpoint 2 | 3 | import "fmt" 4 | 5 | const ( 6 | UDP int32 = 0 7 | TCP int32 = 1 8 | SSL int32 = 2 9 | ) 10 | 11 | type AuthType int32 12 | type WeightType int32 13 | 14 | const ( 15 | AuthTypeNone AuthType = iota 16 | AuthTypeLocal 17 | ) 18 | const ( 19 | ELoop WeightType = iota 20 | EStaticWeight 21 | ) 22 | 23 | // Endpoint struct is used record a remote server instance. 24 | type Endpoint struct { 25 | Host string 26 | Port int32 27 | Timeout int32 28 | Istcp int32 //need remove 29 | Grid int32 30 | Qos int32 31 | Weight int32 32 | WeightType int32 33 | AuthType int32 34 | Proto string 35 | Bind string 36 | Container string 37 | SetId string 38 | Key string 39 | } 40 | 41 | // String returns readable string for Endpoint 42 | func (e Endpoint) String() string { 43 | return fmt.Sprintf("%s -h %s -p %d -t %d", e.Proto, e.Host, e.Port, e.Timeout) 44 | } 45 | 46 | func (e Endpoint) HashKey() string { 47 | return e.Host 48 | } 49 | 50 | func (e Endpoint) IsTcp() bool { 51 | return e.Istcp == TCP || e.Istcp == SSL 52 | } 53 | 54 | func (e Endpoint) IsUdp() bool { 55 | return e.Istcp == UDP 56 | } 57 | 58 | func (e Endpoint) IsSSL() bool { 59 | return e.Istcp == SSL 60 | } 61 | -------------------------------------------------------------------------------- /tars/util/endpoint/parse.go: -------------------------------------------------------------------------------- 1 | package endpoint 2 | 3 | import ( 4 | "flag" 5 | "strings" 6 | ) 7 | 8 | // Parse pares string to struct Endpoint, like tcp -h 10.219.139.142 -p 19386 -t 60000 9 | func Parse(endpoint string) Endpoint { 10 | // tcp -h 10.219.139.142 -p 19386 -t 60000 11 | proto := endpoint[0:3] 12 | pFlag := flag.NewFlagSet(proto, flag.ContinueOnError) 13 | var host, bind string 14 | var port, timeout, grid, qos, weight, weightType, authType int 15 | pFlag.StringVar(&host, "h", "", "host") 16 | pFlag.IntVar(&port, "p", 0, "port") 17 | pFlag.IntVar(&timeout, "t", 3000, "timeout") 18 | pFlag.IntVar(&grid, "g", 0, "grid") 19 | pFlag.IntVar(&qos, "q", 0, "qos") 20 | pFlag.IntVar(&weight, "w", -1, "weight") 21 | pFlag.IntVar(&weightType, "v", 0, "weight type") // 权重类型 22 | pFlag.IntVar(&authType, "e", 0, "auth type") // 鉴权类型: enum AUTH_TYPE { AUTH_TYPENONE = 0, AUTH_TYPELOCAL = 1}; 23 | pFlag.StringVar(&bind, "b", "", "bind") 24 | _ = pFlag.Parse(strings.Fields(endpoint)[1:]) 25 | isTcp := int32(0) 26 | if proto == "tcp" { 27 | isTcp = int32(1) 28 | } else if proto == "ssl" { 29 | proto = "tcp" 30 | isTcp = int32(2) 31 | } 32 | if weightType != 0 && (weight == -1 || weight > 100) { 33 | weight = 100 34 | } 35 | e := Endpoint{ 36 | Host: host, 37 | Port: int32(port), 38 | Timeout: int32(timeout), 39 | Istcp: isTcp, 40 | Grid: int32(grid), 41 | Qos: int32(qos), 42 | Weight: int32(weight), 43 | WeightType: int32(weightType), 44 | AuthType: int32(AuthType(authType)), 45 | Proto: proto, 46 | Bind: bind, 47 | } 48 | e.Key = e.String() 49 | return e 50 | } 51 | -------------------------------------------------------------------------------- /tars/util/endpoint/parse_test.go: -------------------------------------------------------------------------------- 1 | package endpoint 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // TestParse tests parsing the endpoint. 9 | func TestParse(t *testing.T) { 10 | tests := []string{ 11 | "tcp -h 127.0.0.1 -p 19386 -t 60000", 12 | "udp -h 127.0.0.1 -p 19386 -t 60000", 13 | "ssl -h 127.0.0.1 -p 19386 -t 60000", 14 | "ssl -h 127.0.0.1 -p 19386 -t 60000 -g 10 -q 10 -w 10 -v 1 -e 0", 15 | } 16 | for _, tt := range tests { 17 | e2 := Parse(tt) 18 | fmt.Printf("Parse: %+v\n", e2) 19 | tars := Endpoint2tars(e2) 20 | fmt.Printf("Endpoint2tars: %+v\n", tars) 21 | fmt.Printf("Tars2endpoint: %+v\n", Tars2endpoint(tars)) 22 | } 23 | fmt.Println(AuthTypeNone, AuthTypeLocal, ELoop, EStaticWeight) 24 | } 25 | -------------------------------------------------------------------------------- /tars/util/gpool/gpool.go: -------------------------------------------------------------------------------- 1 | package gpool 2 | 3 | // Worker goroutine struct. 4 | type Worker struct { 5 | WorkerQueue chan *Worker 6 | JobChannel chan Job 7 | Stop chan struct{} 8 | } 9 | 10 | // Start : start goroutine pool. 11 | func (w *Worker) Start() { 12 | go func() { 13 | var job Job 14 | for { 15 | w.WorkerQueue <- w 16 | select { 17 | case job = <-w.JobChannel: 18 | job() 19 | case <-w.Stop: 20 | w.Stop <- struct{}{} 21 | return 22 | } 23 | } 24 | }() 25 | } 26 | 27 | func newWorker(pool chan *Worker) *Worker { 28 | return &Worker{ 29 | WorkerQueue: pool, 30 | JobChannel: make(chan Job), 31 | Stop: make(chan struct{}), 32 | } 33 | } 34 | 35 | // Job is a function for doing jobs. 36 | type Job func() 37 | 38 | // Pool is goroutine pool config. 39 | type Pool struct { 40 | JobQueue chan Job 41 | WorkerQueue chan *Worker 42 | stop chan struct{} 43 | } 44 | 45 | // NewPool news goroutine pool 46 | func NewPool(numWorkers int, jobQueueLen int) *Pool { 47 | jobQueue := make(chan Job, jobQueueLen) 48 | workerQueue := make(chan *Worker, numWorkers) 49 | 50 | pool := &Pool{ 51 | JobQueue: jobQueue, 52 | WorkerQueue: workerQueue, 53 | stop: make(chan struct{}), 54 | } 55 | pool.Start() 56 | return pool 57 | } 58 | 59 | // Start starts all workers 60 | func (p *Pool) Start() { 61 | for i := 0; i < cap(p.WorkerQueue); i++ { 62 | worker := newWorker(p.WorkerQueue) 63 | worker.Start() 64 | } 65 | 66 | go p.dispatch() 67 | } 68 | 69 | func (p *Pool) dispatch() { 70 | for { 71 | select { 72 | case job := <-p.JobQueue: 73 | worker := <-p.WorkerQueue 74 | worker.JobChannel <- job 75 | case <-p.stop: 76 | for i := 0; i < cap(p.WorkerQueue); i++ { 77 | worker := <-p.WorkerQueue 78 | 79 | worker.Stop <- struct{}{} 80 | <-worker.Stop 81 | } 82 | 83 | p.stop <- struct{}{} 84 | return 85 | } 86 | } 87 | } 88 | 89 | // Release : release all workers 90 | func (p *Pool) Release() { 91 | p.stop <- struct{}{} 92 | <-p.stop 93 | } 94 | -------------------------------------------------------------------------------- /tars/util/gpool/gpool_benchmark_test.go: -------------------------------------------------------------------------------- 1 | package gpool 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | const ( 10 | runTimes = 1000000 11 | poolSize = 50000 12 | queueSize = 5000 13 | ) 14 | 15 | func demoTask() { 16 | time.Sleep(time.Millisecond * 10) 17 | } 18 | 19 | // BenchmarkGoroutine benchmark the goroutine doing tasks. 20 | func BenchmarkGoroutine(b *testing.B) { 21 | var wg sync.WaitGroup 22 | for i := 0; i < b.N; i++ { 23 | wg.Add(runTimes) 24 | 25 | for j := 0; j < runTimes; j++ { 26 | go func() { 27 | defer wg.Done() 28 | demoTask() 29 | }() 30 | } 31 | 32 | wg.Wait() 33 | } 34 | } 35 | 36 | // BenchmarkGpool benchmarks the goroutine pool. 37 | func BenchmarkGpool(b *testing.B) { 38 | pool := NewPool(poolSize, queueSize) 39 | defer pool.Release() 40 | var wg sync.WaitGroup 41 | 42 | for i := 0; i < b.N; i++ { 43 | wg.Add(runTimes) 44 | for j := 0; j < runTimes; j++ { 45 | pool.JobQueue <- func() { 46 | defer wg.Done() 47 | demoTask() 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tars/util/gpool/gpool_test.go: -------------------------------------------------------------------------------- 1 | package gpool 2 | 3 | import ( 4 | "runtime" 5 | "sync" 6 | "sync/atomic" 7 | "testing" 8 | ) 9 | 10 | func init() { 11 | println("using MAXPROC") 12 | numCPUs := runtime.NumCPU() 13 | runtime.GOMAXPROCS(numCPUs) 14 | } 15 | 16 | // TestNewPool test new goroutine pool 17 | func TestNewPool(t *testing.T) { 18 | pool := NewPool(1000, 10000) 19 | defer pool.Release() 20 | 21 | iterations := 1000000 22 | var counter uint64 23 | 24 | wg := sync.WaitGroup{} 25 | wg.Add(iterations) 26 | for i := 0; i < iterations; i++ { 27 | arg := uint64(1) 28 | job := func() { 29 | defer wg.Done() 30 | atomic.AddUint64(&counter, arg) 31 | } 32 | 33 | pool.JobQueue <- job 34 | } 35 | wg.Wait() 36 | 37 | counterFinal := atomic.LoadUint64(&counter) 38 | if uint64(iterations) != counterFinal { 39 | t.Errorf("iterations %v is not equal counterFinal %v", iterations, counterFinal) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tars/util/grace/grace.go: -------------------------------------------------------------------------------- 1 | package grace 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "strconv" 8 | "sync" 9 | ) 10 | 11 | var ( 12 | // InheritFdPrefix marks the fd inherited from parent process 13 | InheritFdPrefix = "LISTEN_FD_INHERIT" 14 | 15 | allListenFds *sync.Map 16 | ) 17 | 18 | func init() { 19 | allListenFds = &sync.Map{} 20 | } 21 | 22 | // CreateListener creates a listener from inherited fd 23 | // if there is no inherited fd, create a now one. 24 | func CreateListener(proto string, addr string) (net.Listener, error) { 25 | key := fmt.Sprintf("%s_%s_%s", InheritFdPrefix, proto, addr) 26 | val := os.Getenv(key) 27 | if val != "" { 28 | fd, err := strconv.Atoi(val) 29 | if err != nil { 30 | goto CreateTcp 31 | } 32 | file := os.NewFile(uintptr(fd), "listener") 33 | ln, err := net.FileListener(file) 34 | if err != nil { 35 | file.Close() 36 | goto CreateTcp 37 | } 38 | allListenFds.Store(key, ln) 39 | return ln, nil 40 | } 41 | // not inherit, create new 42 | CreateTcp: 43 | ln, err := net.Listen(proto, addr) 44 | if err == nil { 45 | allListenFds.Store(key, ln) 46 | } 47 | return ln, err 48 | } 49 | 50 | // CreateUDPConn creates a udp connection from inherited fd 51 | // if there is no inherited fd, create a now one. 52 | func CreateUDPConn(addr string) (*net.UDPConn, error) { 53 | proto := "udp" 54 | key := fmt.Sprintf("%s_%s_%s", InheritFdPrefix, proto, addr) 55 | val := os.Getenv(key) 56 | if val != "" { 57 | fd, err := strconv.Atoi(val) 58 | if err != nil { 59 | goto CreateUdp 60 | } 61 | file := os.NewFile(uintptr(fd), "listener") 62 | conn, err := net.FileConn(file) 63 | if err != nil { 64 | file.Close() 65 | goto CreateUdp 66 | } 67 | udpConn := conn.(*net.UDPConn) 68 | allListenFds.Store(key, udpConn) 69 | return udpConn, nil 70 | } 71 | // not inherit, create new 72 | CreateUdp: 73 | uaddr, err := net.ResolveUDPAddr("udp4", addr) 74 | if err != nil { 75 | return nil, err 76 | } 77 | conn, err := net.ListenUDP("udp4", uaddr) 78 | if err == nil { 79 | allListenFds.Store(key, conn) 80 | } 81 | return conn, err 82 | } 83 | 84 | // GetAllListenFiles returns all listen files 85 | func GetAllListenFiles() map[string]*os.File { 86 | files := make(map[string]*os.File) 87 | allListenFds.Range(func(k, v interface{}) bool { 88 | key := k.(string) 89 | val := v.(filer) 90 | if file, err := val.File(); err == nil { 91 | files[key] = file 92 | } 93 | return true 94 | }) 95 | return files 96 | } 97 | 98 | type filer interface { 99 | File() (*os.File, error) 100 | } 101 | -------------------------------------------------------------------------------- /tars/util/grace/grace_test.go: -------------------------------------------------------------------------------- 1 | package grace 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "testing" 8 | ) 9 | 10 | func TestListener(t *testing.T) { 11 | proto, addr := "tcp", "localhost:3333" 12 | _, err := CreateListener(proto, addr) 13 | key := fmt.Sprintf("%s_%s_%s", InheritFdPrefix, proto, addr) 14 | fmt.Println(err, key, os.Getenv(key)) 15 | cmd := exec.Command("lsof", "-p", fmt.Sprint(os.Getpid())) 16 | cmd.Stdout = os.Stdout 17 | cmd.Stderr = os.Stderr 18 | cmd.Start() 19 | cmd.Wait() 20 | addr = "localhost:3334" 21 | _, err = CreateUDPConn(addr) 22 | key = fmt.Sprintf("%s_%s_%s", InheritFdPrefix, "udp", addr) 23 | fmt.Println(err, key, os.Getenv(key)) 24 | cmd = exec.Command("lsof", "-p", fmt.Sprint(os.Getpid())) 25 | cmd.Stdout = os.Stdout 26 | cmd.Stderr = os.Stderr 27 | cmd.Start() 28 | cmd.Wait() 29 | } 30 | -------------------------------------------------------------------------------- /tars/util/grace/signal_unix.go: -------------------------------------------------------------------------------- 1 | //go:build linux || darwin 2 | // +build linux darwin 3 | 4 | package grace 5 | 6 | import ( 7 | "os" 8 | "os/signal" 9 | "syscall" 10 | ) 11 | 12 | type handlerFunc func() 13 | 14 | // GraceHandler set the signal handler for grace restart 15 | func GraceHandler(userFunc, stopFunc handlerFunc) { 16 | ch := make(chan os.Signal, 10) 17 | // remove syscall.SIGKILL 18 | signal.Notify(ch, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGTERM, os.Interrupt) 19 | for { 20 | sig := <-ch 21 | switch sig { 22 | case syscall.SIGUSR1: 23 | userFunc() 24 | case syscall.SIGUSR2, syscall.SIGTERM, os.Interrupt: // remove syscall.SIGKILL 25 | signal.Stop(ch) 26 | stopFunc() 27 | } 28 | } 29 | } 30 | 31 | // SignalUSR2 send signal USR2 to pid 32 | func SignalUSR2(pid int) { 33 | syscall.Kill(pid, syscall.SIGUSR2) 34 | } 35 | -------------------------------------------------------------------------------- /tars/util/grace/signal_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package grace 5 | 6 | type handlerFunc func() 7 | 8 | // GraceHandler is not supported in windows 9 | func GraceHandler(stopFunc, userFunc handlerFunc) { 10 | } 11 | 12 | // SignalUSR2 is not supported in windows 13 | func SignalUSR2(pid int) { 14 | } 15 | -------------------------------------------------------------------------------- /tars/util/gtime/gtime.go: -------------------------------------------------------------------------------- 1 | package gtime 2 | 3 | import "time" 4 | 5 | var ( 6 | // CurrUnixTime is current unix time 7 | CurrUnixTime int64 8 | CurrDateTime string 9 | CurrDateHour string 10 | CurrDateDay string 11 | ) 12 | 13 | func init() { 14 | now := time.Now() 15 | CurrUnixTime = now.Unix() 16 | CurrDateTime = now.Format("2006-01-02 15:04:05") 17 | CurrDateHour = now.Format("2006010215") 18 | CurrDateDay = now.Format("20060102") 19 | go func() { 20 | tm := time.NewTimer(time.Second) 21 | for { 22 | now := time.Now() 23 | d := time.Second - time.Duration(now.Nanosecond()) 24 | tm.Reset(d) 25 | <-tm.C 26 | now = time.Now() 27 | CurrUnixTime = now.Unix() 28 | CurrDateTime = now.Format("2006-01-02 15:04:05") 29 | CurrDateHour = now.Format("2006010215") 30 | CurrDateDay = now.Format("20060102") 31 | } 32 | }() 33 | } 34 | -------------------------------------------------------------------------------- /tars/util/gtime/gtime_test.go: -------------------------------------------------------------------------------- 1 | package gtime 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func BenchmarkGtime(b *testing.B) { 9 | for i := 0; i < b.N; i++ { 10 | _ = CurrUnixTime 11 | _ = CurrDateTime 12 | _ = CurrDateHour 13 | _ = CurrDateDay 14 | } 15 | } 16 | 17 | func BenchmarkTime(b *testing.B) { 18 | for i := 0; i < b.N; i++ { 19 | now := time.Now() 20 | _ = now.Format("2006-01-02 15:04:05") 21 | _ = now.Format("2006010215") 22 | _ = now.Format("20060102") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tars/util/rogger/logger_test.go: -------------------------------------------------------------------------------- 1 | package rogger 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | // TestLogger test logger writes. 9 | func TestLogger(t *testing.T) { 10 | SetLevel(DEBUG) 11 | lg := GetLogger("debug") 12 | // lg.SetConsole() 13 | // lg.SetFileRoller("./logs", 3, 1) 14 | // lg.SetDayRoller("./logs", 2) 15 | // lg.SetHourRoller("./logs", 2) 16 | bs := make([]byte, 1024) 17 | longmsg := string(bs) 18 | for i := 0; i < 10; i++ { 19 | lg.Debug("debugxxxxxxxxxxxxxxxxxxxxxxxxxxx") 20 | lg.Info(longmsg) 21 | lg.Warn("warn") 22 | lg.Error("ERROR") 23 | time.Sleep(time.Second) 24 | } 25 | time.Sleep(time.Millisecond * 100) 26 | 27 | FlushLogger() 28 | } 29 | 30 | // XTestGetLogList test get log list 31 | func TestGetLogList(t *testing.T) { 32 | w := NewDateWriter("./logs", "abc", HOUR, 0) 33 | w.cleanOldLogs() 34 | } 35 | 36 | // BenchmarkRogger benchmark rogger writes. 37 | func BenchmarkRogger(b *testing.B) { 38 | SetLevel(DEBUG) 39 | bs := make([]byte, 1024) 40 | longmsg := string(bs) 41 | lg := GetLogger("rogger") 42 | lg.SetFileRoller("./logs", 10, 100) 43 | for i := 0; i < b.N; i++ { 44 | lg.Debug("debugxxxxxxxxxxxxxxxxxxxxxxxxxxx") 45 | lg.Info(longmsg) 46 | lg.Warn("warn") 47 | lg.Error("ERROR") 48 | } 49 | FlushLogger() 50 | } 51 | 52 | // TestColoredLogger test colored logger. 53 | func TestColoredLogger(t *testing.T) { 54 | SetLevel(DEBUG) 55 | Colored() 56 | lg := GetLogger("debug") 57 | bs := make([]byte, 1024) 58 | longmsg := string(bs) 59 | for i := 0; i < 10; i++ { 60 | lg.Debug("debugxxxxxxxxxxxxxxxxxxxxxxxxxxx") 61 | lg.Info(longmsg) 62 | lg.Warn("warn") 63 | lg.Error("ERROR") 64 | func() { 65 | lg.Info("closure func log") 66 | }() 67 | time.Sleep(time.Second) 68 | } 69 | time.Sleep(time.Millisecond * 100) 70 | 71 | FlushLogger() 72 | } 73 | -------------------------------------------------------------------------------- /tars/util/rtimer/timewheel.go: -------------------------------------------------------------------------------- 1 | package rtimer 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | ) 7 | 8 | var ( 9 | timerMap map[time.Duration]*TimeWheel 10 | mapLock = &sync.Mutex{} 11 | accuracy = 20 // means max 1/20 deviation 12 | ) 13 | 14 | func init() { 15 | timerMap = make(map[time.Duration]*TimeWheel) 16 | } 17 | 18 | // After like time.After 19 | func After(t time.Duration) <-chan struct{} { 20 | mapLock.Lock() 21 | defer mapLock.Unlock() 22 | if v, ok := timerMap[t]; ok { 23 | return v.After(t) 24 | } 25 | v := NewTimeWheel(t/time.Duration(accuracy), accuracy+1) 26 | timerMap[t] = v 27 | return v.After(t) 28 | } 29 | 30 | // SetAccuracy sets the accuracy for the timewheel. 31 | // low accuracy usually have better performance. 32 | func SetAccuracy(a int) { 33 | accuracy = a 34 | } 35 | 36 | // TimeWheel struct. 37 | type TimeWheel struct { 38 | lock sync.Mutex 39 | t time.Duration 40 | maxT time.Duration 41 | 42 | ticker *time.Ticker 43 | 44 | timeWheel []chan struct{} 45 | currPos int 46 | } 47 | 48 | // NewTimeWheel new timewheel with size. 49 | func NewTimeWheel(t time.Duration, size int) *TimeWheel { 50 | tw := &TimeWheel{t: t, maxT: t * time.Duration(size)} 51 | 52 | tw.timeWheel = make([]chan struct{}, size) 53 | for i := range tw.timeWheel { 54 | tw.timeWheel[i] = make(chan struct{}) 55 | } 56 | tw.ticker = time.NewTicker(t) 57 | go tw.run() 58 | return tw 59 | } 60 | 61 | // Stop stops the timewheel 62 | func (tw *TimeWheel) Stop() { 63 | tw.ticker.Stop() 64 | } 65 | 66 | // After like time.After 67 | func (tw *TimeWheel) After(timeout time.Duration) <-chan struct{} { 68 | if timeout >= tw.maxT { 69 | panic("timeout is bigger than maxT") 70 | } 71 | 72 | pos := int(timeout / tw.t) 73 | if 0 < pos { 74 | pos-- 75 | } 76 | tw.lock.Lock() 77 | pos = (tw.currPos + pos) % len(tw.timeWheel) 78 | c := tw.timeWheel[pos] 79 | tw.lock.Unlock() 80 | return c 81 | } 82 | 83 | func (tw *TimeWheel) run() { 84 | for range tw.ticker.C { 85 | tw.lock.Lock() 86 | oldestC := tw.timeWheel[tw.currPos] 87 | tw.timeWheel[tw.currPos] = make(chan struct{}) 88 | tw.currPos = (tw.currPos + 1) % len(tw.timeWheel) 89 | tw.lock.Unlock() 90 | close(oldestC) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tars/util/rtimer/timewheel_test.go: -------------------------------------------------------------------------------- 1 | package rtimer 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | // TestTimeWheel test timewheel. 11 | func TestTimeWheel(t *testing.T) { 12 | var deviation int64 13 | var num int64 = 100 14 | sleepTime := time.Millisecond * 20000 15 | 16 | wg := sync.WaitGroup{} 17 | for i := 0; i < 100; i++ { 18 | wg.Add(1) 19 | go func() { 20 | start := time.Now().UnixNano() 21 | <-After(sleepTime) 22 | end := time.Now().UnixNano() 23 | d := (end - start) - int64(sleepTime) 24 | if d >= 0 { 25 | deviation += d 26 | } else { 27 | deviation -= d 28 | } 29 | wg.Done() 30 | }() 31 | time.Sleep(time.Millisecond * 100) 32 | } 33 | wg.Wait() 34 | fmt.Println(float64(deviation) / float64(num*int64(sleepTime))) 35 | } 36 | 37 | // BenchmarkTimeWheel benchmarks timewheel. 38 | func BenchmarkTimeWheel(b *testing.B) { 39 | for i := 0; i < b.N; i++ { 40 | After(time.Millisecond * 100) 41 | } 42 | } 43 | 44 | // BenchmarkTimeBase benchmark origin timer. 45 | func BenchmarkTimeBase(b *testing.B) { 46 | for i := 0; i < b.N; i++ { 47 | time.After(time.Millisecond * 100) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tars/util/set/set.go: -------------------------------------------------------------------------------- 1 | // Package set implement 2 | package set 3 | 4 | import ( 5 | "sync" 6 | "sync/atomic" 7 | ) 8 | 9 | // Set struct 10 | type Set struct { 11 | el sync.Map 12 | length int32 13 | } 14 | 15 | // NewSet news a set 16 | func NewSet(opt ...interface{}) *Set { 17 | s := new(Set) 18 | for _, o := range opt { 19 | s.Add(o) 20 | } 21 | return s 22 | } 23 | 24 | // Add : add an element to Set 25 | func (s *Set) Add(e interface{}) bool { 26 | _, ok := s.el.LoadOrStore(e, s.length) 27 | if !ok { 28 | atomic.AddInt32(&s.length, 1) 29 | } 30 | return ok 31 | } 32 | 33 | // Remove remove an element from set. 34 | func (s *Set) Remove(e interface{}) { 35 | atomic.AddInt32(&s.length, -1) 36 | atomic.CompareAndSwapInt32(&s.length, -1, 0) 37 | s.el.Delete(e) 38 | } 39 | 40 | // Clear : clear the set. 41 | func (s *Set) Clear() { 42 | atomic.SwapInt32(&s.length, 0) 43 | s.el = sync.Map{} 44 | } 45 | 46 | // Slice init set from []interface. 47 | func (s *Set) Slice() (list []interface{}) { 48 | s.el.Range(func(k, v interface{}) bool { 49 | list = append(list, k) 50 | return true 51 | }) 52 | return list 53 | } 54 | 55 | // Len return the length of the set 56 | func (s *Set) Len() int32 { 57 | return s.length 58 | } 59 | 60 | // Has indicates whether the set has the element. 61 | func (s *Set) Has(e interface{}) bool { 62 | if _, ok := s.el.Load(e); ok { 63 | return true 64 | } 65 | return false 66 | } 67 | -------------------------------------------------------------------------------- /tars/util/set/set_test.go: -------------------------------------------------------------------------------- 1 | package set 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSet(t *testing.T) { 8 | s := NewSet("key") 9 | list := s.Slice() 10 | if int32(len(list)) == s.Len() { 11 | t.Log("success:", list) 12 | } else { 13 | t.Error("fail") 14 | } 15 | 16 | e2 := "key" 17 | s.Add(e2) 18 | if s.Len() == 1 { 19 | t.Log("Add success:", s.Slice()) 20 | } else { 21 | t.Error("add fail", s.Slice()) 22 | } 23 | 24 | e3 := "key2" 25 | s.Add(e3) 26 | if s.Len() == 2 { 27 | t.Log("Add success:", s.Slice()) 28 | } else { 29 | t.Error("add fail", s.Slice()) 30 | } 31 | 32 | s.Remove(e3) 33 | if s.Len() == 1 { 34 | t.Log("remove success:", s.Slice()) 35 | } else { 36 | t.Error("remove fail", s.Slice()) 37 | } 38 | 39 | if s.Has("key") { 40 | t.Log("has key success") 41 | } else { 42 | t.Error("has error") 43 | } 44 | 45 | if s.Has("key2333") { 46 | t.Error("has error") 47 | } else { 48 | t.Log("has key success") 49 | } 50 | 51 | s.Clear() 52 | if s.Len() == 0 { 53 | t.Log("clear success:", s.Slice()) 54 | } else { 55 | t.Error("clear fail", s.Slice()) 56 | } 57 | 58 | } 59 | 60 | func BenchmarkSet_add(b *testing.B) { 61 | s := new(Set) 62 | for i := 0; i < b.N; i++ { 63 | s.Add(i) 64 | } 65 | } 66 | 67 | func BenchmarkSet_Slice(b *testing.B) { 68 | s := NewSet(1, 2, 3) 69 | for i := 0; i < b.N; i++ { 70 | s.Slice() 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tars/util/tools/convert.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | import "unsafe" 4 | 5 | // ByteToInt8 convert []byte to []int8 6 | func ByteToInt8(s []byte) []int8 { 7 | d := *(*[]int8)(unsafe.Pointer(&s)) 8 | return d 9 | } 10 | 11 | // Int8ToByte convert []int8 to []byte 12 | func Int8ToByte(s []int8) []byte { 13 | d := *(*[]byte)(unsafe.Pointer(&s)) 14 | return d 15 | } 16 | -------------------------------------------------------------------------------- /tars/util/tools/ip.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | import "net" 4 | 5 | var cacheIP string 6 | 7 | func init() { 8 | GetLocalIP() 9 | } 10 | 11 | func GetLocalIP() string { 12 | if cacheIP != "" { 13 | return cacheIP 14 | } 15 | conn, err := net.Dial("udp", "10.0.0.1:80") 16 | if err != nil { 17 | return "0.0.0.0" 18 | } 19 | defer conn.Close() 20 | 21 | addr := conn.LocalAddr().(*net.UDPAddr) 22 | if addr == nil { 23 | cacheIP = "0.0.0.0" 24 | } else { 25 | cacheIP = addr.IP.String() 26 | } 27 | return cacheIP 28 | } 29 | -------------------------------------------------------------------------------- /tars/util/tools/parser.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | "time" 7 | "unicode" 8 | ) 9 | 10 | const ( 11 | // B byte 12 | B uint64 = 1 13 | // K kilobyte 14 | K uint64 = 1 << (10 * iota) 15 | // M megabyte 16 | M 17 | // G gigabyte 18 | G 19 | // T TeraByte 20 | T 21 | // P PetaByte 22 | P 23 | // E ExaByte 24 | E 25 | ) 26 | 27 | var unitMap = map[string]uint64{ 28 | "B": B, 29 | "K": K, 30 | "KB": K, 31 | "M": M, 32 | "MB": M, 33 | "G": G, 34 | "GB": G, 35 | "T": T, 36 | "TB": T, 37 | "P": P, 38 | "PB": P, 39 | "E": E, 40 | "EB": E, 41 | } 42 | 43 | // ParseLogSizeMb : Translate x(B),xKB,xMB... to uint64 x(MB) 44 | func ParseLogSizeMb(oriSize string) (ret uint64) { 45 | var defaultLogSizeMb uint64 = 100 46 | if oriSize == "" { 47 | return defaultLogSizeMb 48 | } 49 | iLogSize, err := strconv.ParseUint(oriSize, 10, 64) 50 | if err == nil { 51 | ret = iLogSize / 1024 / 1024 52 | if ret == 0 { 53 | return defaultLogSizeMb 54 | } 55 | return ret 56 | } 57 | sLogSize := "" 58 | sUnit := "" 59 | for idx, c := range oriSize { 60 | if !unicode.IsDigit(c) { 61 | sLogSize = strings.TrimSpace(oriSize[:idx]) 62 | sUnit = strings.TrimSpace(oriSize[idx:]) 63 | break 64 | } 65 | } 66 | if sLogSize == "" { 67 | return defaultLogSizeMb 68 | } 69 | iLogSize, err = strconv.ParseUint(sLogSize, 10, 64) 70 | if err != nil { 71 | return defaultLogSizeMb 72 | } 73 | sUnit = strings.ToUpper(sUnit) 74 | iUnit, exists := unitMap[sUnit] 75 | if !exists { 76 | return defaultLogSizeMb 77 | } 78 | ret = iLogSize * iUnit / 1024 / 1024 79 | if ret == 0 { 80 | ret = defaultLogSizeMb 81 | } 82 | return ret 83 | } 84 | 85 | // ParseLogNum : Parse uint64 from string 86 | func ParseLogNum(strVal string) (ret uint64) { 87 | var defaultLogNum uint64 = 10 88 | ret, err := strconv.ParseUint(strVal, 10, 64) 89 | if err != nil { 90 | return defaultLogNum 91 | } 92 | return ret 93 | } 94 | 95 | // ParseTimeOut : Parse time.Duration from int 96 | func ParseTimeOut(timeout int) (ret time.Duration) { 97 | ret = time.Duration(timeout) * time.Millisecond 98 | return ret 99 | } 100 | 101 | // ParseStrBool : Parse bool from string 102 | func ParseStrBool(delay string) (ret bool) { 103 | if delay == "" { 104 | return false 105 | } 106 | ret, err := strconv.ParseBool(delay) 107 | if err != nil { 108 | return false 109 | } 110 | return ret 111 | } 112 | -------------------------------------------------------------------------------- /tars/util/tools/unique.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | // UniqueInts Return unique element list of list a 4 | func UniqueInts(a []int) (b []int) { 5 | m := map[int]bool{} 6 | for _, v := range a { 7 | if _, ok := m[v]; !ok { 8 | b = append(b, v) 9 | m[v] = true 10 | } 11 | } 12 | return b 13 | } 14 | -------------------------------------------------------------------------------- /tars/util/tools/upperbound.go: -------------------------------------------------------------------------------- 1 | package tools 2 | 3 | // UpperBound Return the upperbound index for in 4 | func UpperBound(sortedArray []int, in int) (index int) { 5 | for i, v := range sortedArray { 6 | if in <= v { 7 | index = i 8 | return 9 | } 10 | index = i 11 | } 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /tars/util/trace/id_generator.go: -------------------------------------------------------------------------------- 1 | package trace 2 | 3 | import ( 4 | crand "crypto/rand" 5 | "encoding/binary" 6 | "encoding/hex" 7 | "math/rand" 8 | "sync" 9 | ) 10 | 11 | type randomIDGenerator struct { 12 | sync.Mutex 13 | randSource *rand.Rand 14 | } 15 | 16 | func newGenerator() *randomIDGenerator { 17 | var rngSeed int64 18 | _ = binary.Read(crand.Reader, binary.LittleEndian, &rngSeed) 19 | return &randomIDGenerator{randSource: rand.New(rand.NewSource(rngSeed))} 20 | } 21 | 22 | // NewSpanID returns a non-zero span ID from a randomly-chosen sequence. 23 | func (gen *randomIDGenerator) NewSpanID() string { 24 | gen.Lock() 25 | defer gen.Unlock() 26 | sid := [8]byte{} 27 | _, _ = gen.randSource.Read(sid[:]) 28 | return hex.EncodeToString(sid[:]) 29 | } 30 | 31 | // NewTraceID returns a non-zero trace ID from a randomly-chosen sequence. 32 | func (gen *randomIDGenerator) NewTraceID() string { 33 | gen.Lock() 34 | defer gen.Unlock() 35 | tid := [16]byte{} 36 | _, _ = gen.randSource.Read(tid[:]) 37 | return hex.EncodeToString(tid[:]) 38 | } 39 | 40 | // NewIDs returns a non-zero trace ID and a non-zero span ID from a 41 | // randomly-chosen sequence. 42 | func (gen *randomIDGenerator) NewIDs() (string, string) { 43 | gen.Lock() 44 | defer gen.Unlock() 45 | tid := [16]byte{} 46 | _, _ = gen.randSource.Read(tid[:]) 47 | sid := [8]byte{} 48 | _, _ = gen.randSource.Read(sid[:]) 49 | return hex.EncodeToString(tid[:]), hex.EncodeToString(sid[:]) 50 | } 51 | --------------------------------------------------------------------------------