Compare commits
82 Commits
Author | SHA1 | Date | |
---|---|---|---|
0257eae936 | |||
58f03d05e7 | |||
60340a749b | |||
56b0df5b7a | |||
|
bb59d5a2fd | ||
67d5dc7e28 | |||
797c0f822d | |||
8546140e22 | |||
92b125c1ce | |||
8f7eebc24f | |||
b0def96d14 | |||
927ca879b2 | |||
00450c9cc7 | |||
534bce2d20 | |||
53949be0cc | |||
d8fe2ff8b4 | |||
53b5ee2c6f | |||
dfd85cd871 | |||
52182261af | |||
1f3834e187 | |||
0354873c3a | |||
8e5e2167cd | |||
c26a7db47c | |||
74765b4c5f | |||
8bd7323af1 | |||
|
899dc8b3bc | ||
6e6c31b5dd | |||
94929878fe | |||
8ce469a09e | |||
88788776d2 | |||
e143e2b547 | |||
a36f99e30b | |||
326ee53333 | |||
1244c5bb4d | |||
4ccc8a9c85 | |||
8a2e84d489 | |||
d29363b78d | |||
734f751055 | |||
55d8a9ee20 | |||
07c93042ba | |||
b9bbfdf159 | |||
fbad257acc | |||
1829febb6e | |||
7838fa62a8 | |||
332803d8de | |||
11c868d476 | |||
38d6e482d7 | |||
07d4085201 | |||
45f30c0be3 | |||
bcaea675a7 | |||
3087ba1d73 | |||
3f5b19497c | |||
37d937d7ae | |||
7d68f2396e | |||
0854a7ea72 | |||
5eb0e56373 | |||
6af837fd25 | |||
ada59119cc | |||
8abc913b28 | |||
3247d144a8 | |||
7b2e3cc8aa | |||
8688179acd | |||
3e40bac5f4 | |||
e3fee6f8a6 | |||
15c020fac5 | |||
3bc046e5d4 | |||
542f36cfa5 | |||
8237e6a08e | |||
ecb60e4dc5 | |||
a1999ff81c | |||
d0f2bc8346 | |||
|
dd29bf457e | ||
d062c248e3 | |||
875f66d36e | |||
818a0e6356 | |||
56e02ec463 | |||
6ca851401d | |||
bd8216b397 | |||
2b13b3f128 | |||
9957380b6d | |||
e10f8c0fa0 | |||
45252fe4a6 |
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@@ -3,6 +3,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
- v3
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: test
|
name: test
|
||||||
|
25
.github/workflows/codeql-analysis.yml
vendored
25
.github/workflows/codeql-analysis.yml
vendored
@@ -9,20 +9,24 @@
|
|||||||
# the `language` matrix defined below to confirm you have the correct set of
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
# supported CodeQL languages.
|
# supported CodeQL languages.
|
||||||
#
|
#
|
||||||
name: "CodeQL"
|
name: "codeql"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["prbuild"]
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master, v3 ]
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: [ master ]
|
branches: [ master, v3 ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '34 1 * * 0'
|
- cron: '34 1 * * 0'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
name: Analyze
|
name: analyze
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
actions: read
|
actions: read
|
||||||
@@ -38,11 +42,14 @@ jobs:
|
|||||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
- name: setup
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.16
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: init
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@v1
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
@@ -53,7 +60,7 @@ jobs:
|
|||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: autobuild
|
||||||
uses: github/codeql-action/autobuild@v1
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
@@ -67,5 +74,5 @@ jobs:
|
|||||||
# make bootstrap
|
# make bootstrap
|
||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: analyze
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v1
|
||||||
|
31
.github/workflows/dependabot-automerge.yml
vendored
Normal file
31
.github/workflows/dependabot-automerge.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
name: "prautomerge"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [assigned, opened, synchronize, reopened]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dependabot:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.actor == 'dependabot[bot]' }}
|
||||||
|
steps:
|
||||||
|
- name: metadata
|
||||||
|
id: metadata
|
||||||
|
uses: dependabot/fetch-metadata@v1.1.1
|
||||||
|
with:
|
||||||
|
github-token: "${{ secrets.TOKEN }}"
|
||||||
|
- name: approve
|
||||||
|
run: gh pr review --approve "$PR_URL"
|
||||||
|
env:
|
||||||
|
PR_URL: ${{github.event.pull_request.html_url}}
|
||||||
|
GITHUB_TOKEN: ${{secrets.TOKEN}}
|
||||||
|
- name: merge
|
||||||
|
if: ${{contains(steps.metadata.outputs.dependency-names, 'go.unistack.org')}}
|
||||||
|
run: gh pr merge --auto --merge "$PR_URL"
|
||||||
|
env:
|
||||||
|
PR_URL: ${{github.event.pull_request.html_url}}
|
||||||
|
GITHUB_TOKEN: ${{secrets.TOKEN}}
|
1
.github/workflows/pr.yml
vendored
1
.github/workflows/pr.yml
vendored
@@ -3,6 +3,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
- v3
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: test
|
name: test
|
||||||
|
@@ -30,7 +30,7 @@ linters:
|
|||||||
- gofmt
|
- gofmt
|
||||||
- gofumpt
|
- gofumpt
|
||||||
- goimports
|
- goimports
|
||||||
- golint
|
- revive
|
||||||
- gosec
|
- gosec
|
||||||
- makezero
|
- makezero
|
||||||
- misspell
|
- misspell
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Micro [](https://opensource.org/licenses/Apache-2.0) [](https://pkg.go.dev/github.com/unistack-org/micro/v3?tab=overview) [](https://github.com/unistack-org/micro/actions?query=workflow%3Abuild+branch%3Amaster+event%3Apush) [](https://goreportcard.com/report/github.com/unistack-org/micro) [](https://unistack-org.slack.com/messages/default)
|
# Micro [](https://opensource.org/licenses/Apache-2.0) [](https://pkg.go.dev/github.com/unistack-org/micro/v3?tab=overview) [](https://github.com/unistack-org/micro/actions?query=workflow%3Abuild+branch%3Amaster+event%3Apush) [](https://goreportcard.com/report/go.unistack.org/micro/v3) [](https://unistack-org.slack.com/messages/default)
|
||||||
|
|
||||||
Micro is a standard library for microservices.
|
Micro is a standard library for microservices.
|
||||||
|
|
||||||
|
19
api/api.go
19
api/api.go
@@ -1,15 +1,16 @@
|
|||||||
package api
|
package api // import "go.unistack.org/micro/v3/api"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
"github.com/unistack-org/micro/v3/register"
|
"go.unistack.org/micro/v3/register"
|
||||||
"github.com/unistack-org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// nolint: revive
|
||||||
// Api interface
|
// Api interface
|
||||||
type Api interface {
|
type Api interface {
|
||||||
// Initialise options
|
// Initialise options
|
||||||
@@ -125,14 +126,14 @@ func Validate(e *Endpoint) error {
|
|||||||
ps := p[0]
|
ps := p[0]
|
||||||
pe := p[len(p)-1]
|
pe := p[len(p)-1]
|
||||||
|
|
||||||
if ps == '^' && pe == '$' {
|
switch {
|
||||||
_, err := regexp.CompilePOSIX(p)
|
case ps == '^' && pe == '$':
|
||||||
if err != nil {
|
if _, err := regexp.CompilePOSIX(p); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if ps == '^' && pe != '$' {
|
case ps == '^' && pe != '$':
|
||||||
return errors.New("invalid path")
|
return errors.New("invalid path")
|
||||||
} else if ps != '^' && pe == '$' {
|
case ps != '^' && pe == '$':
|
||||||
return errors.New("invalid path")
|
return errors.New("invalid path")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package handler provides http handlers
|
// Package handler provides http handlers
|
||||||
package handler
|
package handler // import "go.unistack.org/micro/v3/api/handler"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/api/router"
|
"go.unistack.org/micro/v3/api/router"
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultMaxRecvSize specifies max recv size for handler
|
// DefaultMaxRecvSize specifies max recv size for handler
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
// Package grpc resolves a grpc service like /greeter.Say/Hello to greeter service
|
// Package grpc resolves a grpc service like /greeter.Say/Hello to greeter service
|
||||||
package grpc
|
package grpc // import "go.unistack.org/micro/v3/api/resolver/grpc"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api/resolver"
|
"go.unistack.org/micro/v3/api/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resolver struct
|
// Resolver struct
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
// Package host resolves using http host
|
// Package host resolves using http host
|
||||||
package host
|
package host // import "go.unistack.org/micro/v3/api/resolver/host"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api/resolver"
|
"go.unistack.org/micro/v3/api/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
type hostResolver struct {
|
type hostResolver struct {
|
||||||
|
@@ -3,7 +3,7 @@ package resolver
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/register"
|
"go.unistack.org/micro/v3/register"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options struct
|
// Options struct
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
// Package path resolves using http path
|
// Package path resolves using http path
|
||||||
package path
|
package path // import "go.unistack.org/micro/v3/api/resolver/path"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api/resolver"
|
"go.unistack.org/micro/v3/api/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resolver the path resolver
|
// Resolver the path resolver
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package resolver resolves a http request to an endpoint
|
// Package resolver resolves a http request to an endpoint
|
||||||
package resolver
|
package resolver // import "go.unistack.org/micro/v3/api/resolver"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
// Package subdomain is a resolver which uses the subdomain to determine the domain to route to. It
|
// Package subdomain is a resolver which uses the subdomain to determine the domain to route to. It
|
||||||
// offloads the endpoint resolution to a child resolver which is provided in New.
|
// offloads the endpoint resolution to a child resolver which is provided in New.
|
||||||
package subdomain
|
package subdomain // import "go.unistack.org/micro/v3/api/resolver/subdomain"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api/resolver"
|
"go.unistack.org/micro/v3/api/resolver"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"golang.org/x/net/publicsuffix"
|
"golang.org/x/net/publicsuffix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api/resolver/vpath"
|
"go.unistack.org/micro/v3/api/resolver/vpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestResolve(t *testing.T) {
|
func TestResolve(t *testing.T) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package vpath resolves using http path and recognised versioned urls
|
// Package vpath resolves using http path and recognised versioned urls
|
||||||
package vpath
|
package vpath // import "go.unistack.org/micro/v3/api/resolver/vpath"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api/resolver"
|
"go.unistack.org/micro/v3/api/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewResolver creates new vpath api resolver
|
// NewResolver creates new vpath api resolver
|
||||||
|
@@ -3,10 +3,10 @@ package router
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api/resolver"
|
"go.unistack.org/micro/v3/api/resolver"
|
||||||
"github.com/unistack-org/micro/v3/api/resolver/vpath"
|
"go.unistack.org/micro/v3/api/resolver/vpath"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/register"
|
"go.unistack.org/micro/v3/register"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options holds the options for api router
|
// Options holds the options for api router
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
// Package router provides api service routing
|
// Package router provides api service routing
|
||||||
package router
|
package router // import "go.unistack.org/micro/v3/api/router"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/api"
|
"go.unistack.org/micro/v3/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultRouter contains default router implementation
|
// DefaultRouter contains default router implementation
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
// Package auth provides authentication and authorization capability
|
// Package auth provides authentication and authorization capability
|
||||||
package auth
|
package auth // import "go.unistack.org/micro/v3/auth"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/util/id"
|
"go.unistack.org/micro/v3/util/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type noopAuth struct {
|
type noopAuth struct {
|
||||||
|
@@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/store"
|
"go.unistack.org/micro/v3/store"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewOptions creates Options struct from slice of options
|
// NewOptions creates Options struct from slice of options
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
// Package broker is an interface used for asynchronous messaging
|
// Package broker is an interface used for asynchronous messaging
|
||||||
package broker
|
package broker // import "go.unistack.org/micro/v3/broker"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultBroker default memory broker
|
// DefaultBroker default memory broker
|
||||||
|
176
broker/memory.go
176
broker/memory.go
@@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
maddr "github.com/unistack-org/micro/v3/util/addr"
|
maddr "go.unistack.org/micro/v3/util/addr"
|
||||||
"github.com/unistack-org/micro/v3/util/id"
|
"go.unistack.org/micro/v3/util/id"
|
||||||
mnet "github.com/unistack-org/micro/v3/util/net"
|
mnet "go.unistack.org/micro/v3/util/net"
|
||||||
"github.com/unistack-org/micro/v3/util/rand"
|
"go.unistack.org/micro/v3/util/rand"
|
||||||
)
|
)
|
||||||
|
|
||||||
type memoryBroker struct {
|
type memoryBroker struct {
|
||||||
@@ -89,36 +89,15 @@ func (m *memoryBroker) Init(opts ...Option) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryBroker) Publish(ctx context.Context, topic string, msg *Message, opts ...PublishOption) error {
|
func (m *memoryBroker) Publish(ctx context.Context, topic string, msg *Message, opts ...PublishOption) error {
|
||||||
m.RLock()
|
msg.Header.Set(metadata.HeaderTopic, topic)
|
||||||
if !m.connected {
|
return m.publish(ctx, []*Message{msg}, opts...)
|
||||||
m.RUnlock()
|
|
||||||
return ErrNotConnected
|
|
||||||
}
|
|
||||||
m.RUnlock()
|
|
||||||
|
|
||||||
options := NewPublishOptions(opts...)
|
|
||||||
vs := make([]msgWrapper, 0, 1)
|
|
||||||
if m.opts.Codec == nil || options.BodyOnly {
|
|
||||||
topic, _ := msg.Header.Get(metadata.HeaderTopic)
|
|
||||||
vs = append(vs, msgWrapper{topic: topic, body: msg})
|
|
||||||
} else {
|
|
||||||
topic, _ := msg.Header.Get(metadata.HeaderTopic)
|
|
||||||
buf, err := m.opts.Codec.Marshal(msg)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
vs = append(vs, msgWrapper{topic: topic, body: buf})
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.publish(ctx, vs, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
type msgWrapper struct {
|
|
||||||
topic string
|
|
||||||
body interface{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memoryBroker) BatchPublish(ctx context.Context, msgs []*Message, opts ...PublishOption) error {
|
func (m *memoryBroker) BatchPublish(ctx context.Context, msgs []*Message, opts ...PublishOption) error {
|
||||||
|
return m.publish(ctx, msgs, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *memoryBroker) publish(ctx context.Context, msgs []*Message, opts ...PublishOption) error {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
if !m.connected {
|
if !m.connected {
|
||||||
m.RUnlock()
|
m.RUnlock()
|
||||||
@@ -126,88 +105,81 @@ func (m *memoryBroker) BatchPublish(ctx context.Context, msgs []*Message, opts .
|
|||||||
}
|
}
|
||||||
m.RUnlock()
|
m.RUnlock()
|
||||||
|
|
||||||
options := NewPublishOptions(opts...)
|
|
||||||
vs := make([]msgWrapper, 0, len(msgs))
|
|
||||||
if m.opts.Codec == nil || options.BodyOnly {
|
|
||||||
for _, msg := range msgs {
|
|
||||||
topic, _ := msg.Header.Get(metadata.HeaderTopic)
|
|
||||||
vs = append(vs, msgWrapper{topic: topic, body: msg})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for _, msg := range msgs {
|
|
||||||
topic, _ := msg.Header.Get(metadata.HeaderTopic)
|
|
||||||
buf, err := m.opts.Codec.Marshal(msg)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
vs = append(vs, msgWrapper{topic: topic, body: buf})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m.publish(ctx, vs, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *memoryBroker) publish(ctx context.Context, vs []msgWrapper, opts ...PublishOption) error {
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
msgTopicMap := make(map[string]Events)
|
select {
|
||||||
for _, v := range vs {
|
case <-ctx.Done():
|
||||||
p := &memoryEvent{
|
return ctx.Err()
|
||||||
topic: v.topic,
|
default:
|
||||||
message: v.body,
|
options := NewPublishOptions(opts...)
|
||||||
opts: m.opts,
|
|
||||||
}
|
|
||||||
msgTopicMap[p.topic] = append(msgTopicMap[p.topic], p)
|
|
||||||
}
|
|
||||||
|
|
||||||
beh := m.opts.BatchErrorHandler
|
msgTopicMap := make(map[string]Events)
|
||||||
eh := m.opts.ErrorHandler
|
for _, v := range msgs {
|
||||||
|
p := &memoryEvent{opts: m.opts}
|
||||||
|
|
||||||
for t, ms := range msgTopicMap {
|
if m.opts.Codec == nil || options.BodyOnly {
|
||||||
m.RLock()
|
p.topic, _ = v.Header.Get(metadata.HeaderTopic)
|
||||||
subs, ok := m.subscribers[t]
|
p.message = v.Body
|
||||||
m.RUnlock()
|
} else {
|
||||||
if !ok {
|
p.topic, _ = v.Header.Get(metadata.HeaderTopic)
|
||||||
continue
|
p.message, err = m.opts.Codec.Marshal(v)
|
||||||
}
|
if err != nil {
|
||||||
|
return err
|
||||||
for _, sub := range subs {
|
|
||||||
// batch processing
|
|
||||||
if sub.batchhandler != nil {
|
|
||||||
if err = sub.batchhandler(ms); err != nil {
|
|
||||||
ms.SetError(err)
|
|
||||||
if sub.opts.BatchErrorHandler != nil {
|
|
||||||
beh = sub.opts.BatchErrorHandler
|
|
||||||
}
|
|
||||||
if beh != nil {
|
|
||||||
beh(ms)
|
|
||||||
} else if m.opts.Logger.V(logger.ErrorLevel) {
|
|
||||||
m.opts.Logger.Error(m.opts.Context, err.Error())
|
|
||||||
}
|
|
||||||
} else if sub.opts.AutoAck {
|
|
||||||
if err = ms.Ack(); err != nil {
|
|
||||||
m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// single processing
|
msgTopicMap[p.topic] = append(msgTopicMap[p.topic], p)
|
||||||
if sub.handler != nil {
|
}
|
||||||
for _, p := range ms {
|
|
||||||
if err = sub.handler(p); err != nil {
|
beh := m.opts.BatchErrorHandler
|
||||||
p.SetError(err)
|
eh := m.opts.ErrorHandler
|
||||||
if sub.opts.ErrorHandler != nil {
|
|
||||||
eh = sub.opts.ErrorHandler
|
for t, ms := range msgTopicMap {
|
||||||
}
|
m.RLock()
|
||||||
if eh != nil {
|
subs, ok := m.subscribers[t]
|
||||||
eh(p)
|
m.RUnlock()
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sub := range subs {
|
||||||
|
if sub.opts.BatchErrorHandler != nil {
|
||||||
|
beh = sub.opts.BatchErrorHandler
|
||||||
|
}
|
||||||
|
if sub.opts.ErrorHandler != nil {
|
||||||
|
eh = sub.opts.ErrorHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
// batch processing
|
||||||
|
case sub.batchhandler != nil:
|
||||||
|
if err = sub.batchhandler(ms); err != nil {
|
||||||
|
ms.SetError(err)
|
||||||
|
if beh != nil {
|
||||||
|
_ = beh(ms)
|
||||||
} else if m.opts.Logger.V(logger.ErrorLevel) {
|
} else if m.opts.Logger.V(logger.ErrorLevel) {
|
||||||
m.opts.Logger.Error(m.opts.Context, err.Error())
|
m.opts.Logger.Error(m.opts.Context, err.Error())
|
||||||
}
|
}
|
||||||
} else if sub.opts.AutoAck {
|
} else if sub.opts.AutoAck {
|
||||||
if err = p.Ack(); err != nil {
|
if err = ms.Ack(); err != nil {
|
||||||
m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err)
|
m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// single processing
|
||||||
|
case sub.handler != nil:
|
||||||
|
for _, p := range ms {
|
||||||
|
if err = sub.handler(p); err != nil {
|
||||||
|
p.SetError(err)
|
||||||
|
if eh != nil {
|
||||||
|
_ = eh(p)
|
||||||
|
} else if m.opts.Logger.V(logger.ErrorLevel) {
|
||||||
|
m.opts.Logger.Error(m.opts.Context, err.Error())
|
||||||
|
}
|
||||||
|
} else if sub.opts.AutoAck {
|
||||||
|
if err = p.Ack(); err != nil {
|
||||||
|
m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMemoryBatchBroker(t *testing.T) {
|
func TestMemoryBatchBroker(t *testing.T) {
|
||||||
@@ -28,7 +28,7 @@ func TestMemoryBatchBroker(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error subscribing %v", err)
|
t.Fatalf("Unexpected error subscribing %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs := make([]*Message, 0, 0)
|
msgs := make([]*Message, 0, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
message := &Message{
|
message := &Message{
|
||||||
Header: map[string]string{
|
Header: map[string]string{
|
||||||
@@ -53,6 +53,7 @@ func TestMemoryBatchBroker(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected connect error %v", err)
|
t.Fatalf("Unexpected connect error %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMemoryBroker(t *testing.T) {
|
func TestMemoryBroker(t *testing.T) {
|
||||||
b := NewBroker()
|
b := NewBroker()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@@ -73,7 +74,7 @@ func TestMemoryBroker(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error subscribing %v", err)
|
t.Fatalf("Unexpected error subscribing %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs := make([]*Message, 0, 0)
|
msgs := make([]*Message, 0, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
message := &Message{
|
message := &Message{
|
||||||
Header: map[string]string{
|
Header: map[string]string{
|
||||||
|
@@ -5,11 +5,11 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/register"
|
"go.unistack.org/micro/v3/register"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options struct
|
// Options struct
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package build is for building source into a package
|
// Package build is for building source into a package
|
||||||
package build
|
package build // import "go.unistack.org/micro/v3/build"
|
||||||
|
|
||||||
// Build is an interface for building packages
|
// Build is an interface for building packages
|
||||||
type Build interface {
|
type Build interface {
|
||||||
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/util/backoff"
|
"go.unistack.org/micro/v3/util/backoff"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BackoffFunc is the backoff call func
|
// BackoffFunc is the backoff call func
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
// Package client is an interface for an RPC client
|
// Package client is an interface for an RPC client
|
||||||
package client
|
package client // import "go.unistack.org/micro/v3/client"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -49,6 +49,7 @@ type Message interface {
|
|||||||
Topic() string
|
Topic() string
|
||||||
Payload() interface{}
|
Payload() interface{}
|
||||||
ContentType() string
|
ContentType() string
|
||||||
|
Metadata() metadata.Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request is the interface for a synchronous request used by Call or Stream
|
// Request is the interface for a synchronous request used by Call or Stream
|
||||||
@@ -91,10 +92,16 @@ type Stream interface {
|
|||||||
Send(msg interface{}) error
|
Send(msg interface{}) error
|
||||||
// Recv will decode and read a response
|
// Recv will decode and read a response
|
||||||
Recv(msg interface{}) error
|
Recv(msg interface{}) error
|
||||||
|
// SendMsg will encode and send a request
|
||||||
|
SendMsg(msg interface{}) error
|
||||||
|
// RecvMsg will decode and read a response
|
||||||
|
RecvMsg(msg interface{}) error
|
||||||
// Error returns the stream error
|
// Error returns the stream error
|
||||||
Error() error
|
Error() error
|
||||||
// Close closes the stream
|
// Close closes the stream
|
||||||
Close() error
|
Close() error
|
||||||
|
// CloseSend closes the send direction of the stream
|
||||||
|
CloseSend() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option used by the Client
|
// Option used by the Client
|
||||||
|
@@ -4,15 +4,15 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/errors"
|
"go.unistack.org/micro/v3/errors"
|
||||||
"github.com/unistack-org/micro/v3/router"
|
"go.unistack.org/micro/v3/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LookupFunc is used to lookup routes for a service
|
// LookupFunc is used to lookup routes for a service
|
||||||
type LookupFunc func(context.Context, Request, CallOptions) ([]string, error)
|
type LookupFunc func(context.Context, Request, CallOptions) ([]string, error)
|
||||||
|
|
||||||
// LookupRoute for a request using the router and then choose one using the selector
|
// LookupRoute for a request using the router and then choose one using the selector
|
||||||
func LookupRoute(ctx context.Context, req Request, opts CallOptions) ([]string, error) {
|
func LookupRoute(_ context.Context, req Request, opts CallOptions) ([]string, error) {
|
||||||
// check to see if an address was provided as a call option
|
// check to see if an address was provided as a call option
|
||||||
if len(opts.Address) > 0 {
|
if len(opts.Address) > 0 {
|
||||||
return opts.Address, nil
|
return opts.Address, nil
|
||||||
|
@@ -3,10 +3,10 @@ package client
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/broker"
|
"go.unistack.org/micro/v3/broker"
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/errors"
|
"go.unistack.org/micro/v3/errors"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultCodecs will be used to encode/decode data
|
// DefaultCodecs will be used to encode/decode data
|
||||||
@@ -119,6 +119,14 @@ func (n *noopStream) Recv(interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *noopStream) SendMsg(interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noopStream) RecvMsg(interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (n *noopStream) Error() error {
|
func (n *noopStream) Error() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -127,6 +135,10 @@ func (n *noopStream) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *noopStream) CloseSend() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (n *noopMessage) Topic() string {
|
func (n *noopMessage) Topic() string {
|
||||||
return n.topic
|
return n.topic
|
||||||
}
|
}
|
||||||
@@ -139,6 +151,10 @@ func (n *noopMessage) ContentType() string {
|
|||||||
return n.opts.ContentType
|
return n.opts.ContentType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *noopMessage) Metadata() metadata.Metadata {
|
||||||
|
return n.opts.Metadata
|
||||||
|
}
|
||||||
|
|
||||||
func (n *noopClient) newCodec(contentType string) (codec.Codec, error) {
|
func (n *noopClient) newCodec(contentType string) (codec.Codec, error) {
|
||||||
if cf, ok := n.opts.Codecs[contentType]; ok {
|
if cf, ok := n.opts.Codecs[contentType]; ok {
|
||||||
return cf, nil
|
return cf, nil
|
||||||
|
@@ -5,20 +5,23 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/broker"
|
"go.unistack.org/micro/v3/broker"
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
"github.com/unistack-org/micro/v3/network/transport"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/register"
|
"go.unistack.org/micro/v3/network/transport"
|
||||||
"github.com/unistack-org/micro/v3/router"
|
"go.unistack.org/micro/v3/register"
|
||||||
"github.com/unistack-org/micro/v3/selector"
|
"go.unistack.org/micro/v3/router"
|
||||||
"github.com/unistack-org/micro/v3/selector/random"
|
"go.unistack.org/micro/v3/selector"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/selector/random"
|
||||||
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options holds client options
|
// Options holds client options
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
// Transport used for transfer messages
|
||||||
|
Transport transport.Transport
|
||||||
// Selector used to select needed address
|
// Selector used to select needed address
|
||||||
Selector selector.Selector
|
Selector selector.Selector
|
||||||
// Logger used to log messages
|
// Logger used to log messages
|
||||||
@@ -29,18 +32,16 @@ type Options struct {
|
|||||||
Broker broker.Broker
|
Broker broker.Broker
|
||||||
// Meter used for metrics
|
// Meter used for metrics
|
||||||
Meter meter.Meter
|
Meter meter.Meter
|
||||||
// Router used to get route
|
|
||||||
Router router.Router
|
|
||||||
// Transport used for transfer messages
|
|
||||||
Transport transport.Transport
|
|
||||||
// Context is used for external options
|
// Context is used for external options
|
||||||
Context context.Context
|
Context context.Context
|
||||||
// Lookup func used to get destination addr
|
// Router used to get route
|
||||||
Lookup LookupFunc
|
Router router.Router
|
||||||
// Codecs map
|
|
||||||
Codecs map[string]codec.Codec
|
|
||||||
// TLSConfig specifies tls.Config for secure connection
|
// TLSConfig specifies tls.Config for secure connection
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
|
// Codecs map
|
||||||
|
Codecs map[string]codec.Codec
|
||||||
|
// Lookup func used to get destination addr
|
||||||
|
Lookup LookupFunc
|
||||||
// Proxy is used for proxy requests
|
// Proxy is used for proxy requests
|
||||||
Proxy string
|
Proxy string
|
||||||
// ContentType is used to select codec
|
// ContentType is used to select codec
|
||||||
@@ -68,12 +69,12 @@ func NewCallOptions(opts ...CallOption) CallOptions {
|
|||||||
|
|
||||||
// CallOptions holds client call options
|
// CallOptions holds client call options
|
||||||
type CallOptions struct {
|
type CallOptions struct {
|
||||||
// Router used for route
|
|
||||||
Router router.Router
|
|
||||||
// Selector selects addr
|
// Selector selects addr
|
||||||
Selector selector.Selector
|
Selector selector.Selector
|
||||||
// Context used for deadline
|
// Context used for deadline
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
// Router used for route
|
||||||
|
Router router.Router
|
||||||
// Retry func used for retries
|
// Retry func used for retries
|
||||||
Retry RetryFunc
|
Retry RetryFunc
|
||||||
// Backoff func used for backoff when retry
|
// Backoff func used for backoff when retry
|
||||||
@@ -82,22 +83,22 @@ type CallOptions struct {
|
|||||||
Network string
|
Network string
|
||||||
// Content-Type
|
// Content-Type
|
||||||
ContentType string
|
ContentType string
|
||||||
// CallWrappers call wrappers
|
// AuthToken string
|
||||||
CallWrappers []CallWrapper
|
AuthToken string
|
||||||
// SelectOptions selector options
|
|
||||||
SelectOptions []selector.SelectOption
|
|
||||||
// Address specifies static addr list
|
// Address specifies static addr list
|
||||||
Address []string
|
Address []string
|
||||||
// Retries specifies retries num
|
// SelectOptions selector options
|
||||||
Retries int
|
SelectOptions []selector.SelectOption
|
||||||
|
// CallWrappers call wrappers
|
||||||
|
CallWrappers []CallWrapper
|
||||||
// StreamTimeout stream timeout
|
// StreamTimeout stream timeout
|
||||||
StreamTimeout time.Duration
|
StreamTimeout time.Duration
|
||||||
// RequestTimeout request timeout
|
// RequestTimeout request timeout
|
||||||
RequestTimeout time.Duration
|
RequestTimeout time.Duration
|
||||||
// DialTimeout dial timeout
|
// DialTimeout dial timeout
|
||||||
DialTimeout time.Duration
|
DialTimeout time.Duration
|
||||||
// AuthToken string
|
// Retries specifies retries num
|
||||||
AuthToken string
|
Retries int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context pass context to client
|
// Context pass context to client
|
||||||
@@ -118,17 +119,17 @@ func NewPublishOptions(opts ...PublishOption) PublishOptions {
|
|||||||
|
|
||||||
// PublishOptions holds publish options
|
// PublishOptions holds publish options
|
||||||
type PublishOptions struct {
|
type PublishOptions struct {
|
||||||
// BodyOnly will publish only message body
|
|
||||||
BodyOnly bool
|
|
||||||
// Context used for external options
|
// Context used for external options
|
||||||
Context context.Context
|
Context context.Context
|
||||||
// Exchange topic exchange name
|
// Exchange topic exchange name
|
||||||
Exchange string
|
Exchange string
|
||||||
|
// BodyOnly will publish only message body
|
||||||
|
BodyOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMessageOptions creates message options struct
|
// NewMessageOptions creates message options struct
|
||||||
func NewMessageOptions(opts ...MessageOption) MessageOptions {
|
func NewMessageOptions(opts ...MessageOption) MessageOptions {
|
||||||
options := MessageOptions{}
|
options := MessageOptions{Metadata: metadata.New(1)}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
@@ -137,7 +138,10 @@ func NewMessageOptions(opts ...MessageOption) MessageOptions {
|
|||||||
|
|
||||||
// MessageOptions holds client message options
|
// MessageOptions holds client message options
|
||||||
type MessageOptions struct {
|
type MessageOptions struct {
|
||||||
|
// Metadata additional metadata
|
||||||
|
Metadata metadata.Metadata
|
||||||
// ContentType specify content-type of message
|
// ContentType specify content-type of message
|
||||||
|
// deprecated
|
||||||
ContentType string
|
ContentType string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +271,7 @@ func Transport(t transport.Transport) Option {
|
|||||||
func Register(r register.Register) Option {
|
func Register(r register.Register) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
if o.Router != nil {
|
if o.Router != nil {
|
||||||
o.Router.Init(router.Register(r))
|
_ = o.Router.Init(router.Register(r))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,7 +335,7 @@ func TLSConfig(t *tls.Config) Option {
|
|||||||
// already set. Required for Init call below.
|
// already set. Required for Init call below.
|
||||||
|
|
||||||
// set the transport tls
|
// set the transport tls
|
||||||
o.Transport.Init(
|
_ = o.Transport.Init(
|
||||||
transport.TLSConfig(t),
|
transport.TLSConfig(t),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -517,6 +521,7 @@ func WithSelectOptions(sops ...selector.SelectOption) CallOption {
|
|||||||
// Deprecated
|
// Deprecated
|
||||||
func WithMessageContentType(ct string) MessageOption {
|
func WithMessageContentType(ct string) MessageOption {
|
||||||
return func(o *MessageOptions) {
|
return func(o *MessageOptions) {
|
||||||
|
o.Metadata.Set(metadata.HeaderContentType, ct)
|
||||||
o.ContentType = ct
|
o.ContentType = ct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,10 +529,18 @@ func WithMessageContentType(ct string) MessageOption {
|
|||||||
// MessageContentType sets the message content type
|
// MessageContentType sets the message content type
|
||||||
func MessageContentType(ct string) MessageOption {
|
func MessageContentType(ct string) MessageOption {
|
||||||
return func(o *MessageOptions) {
|
return func(o *MessageOptions) {
|
||||||
|
o.Metadata.Set(metadata.HeaderContentType, ct)
|
||||||
o.ContentType = ct
|
o.ContentType = ct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MessageMetadata sets the message metadata
|
||||||
|
func MessageMetadata(k, v string) MessageOption {
|
||||||
|
return func(o *MessageOptions) {
|
||||||
|
o.Metadata.Set(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// StreamingRequest specifies that request is streaming
|
// StreamingRequest specifies that request is streaming
|
||||||
func StreamingRequest(b bool) RequestOption {
|
func StreamingRequest(b bool) RequestOption {
|
||||||
return func(o *RequestOptions) {
|
return func(o *RequestOptions) {
|
||||||
|
@@ -3,7 +3,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/errors"
|
"go.unistack.org/micro/v3/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RetryFunc that returning either false or a non-nil error will result in the call not being retried
|
// RetryFunc that returning either false or a non-nil error will result in the call not being retried
|
||||||
@@ -20,7 +20,7 @@ func RetryNever(ctx context.Context, req Request, retryCount int, err error) (bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RetryOnError retries a request on a 500 or timeout error
|
// RetryOnError retries a request on a 500 or timeout error
|
||||||
func RetryOnError(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
|
func RetryOnError(_ context.Context, _ Request, _ int, err error) (bool, error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testRequest struct {
|
type testRequest struct {
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
// Package codec is an interface for encoding messages
|
// Package codec is an interface for encoding messages
|
||||||
package codec
|
package codec // import "go.unistack.org/micro/v3/codec"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Message types
|
// Message types
|
||||||
@@ -25,7 +25,7 @@ var (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// DefaultMaxMsgSize specifies how much data codec can handle
|
// DefaultMaxMsgSize specifies how much data codec can handle
|
||||||
DefaultMaxMsgSize int = 1024 * 1024 * 4 // 4Mb
|
DefaultMaxMsgSize = 1024 * 1024 * 4 // 4Mb
|
||||||
// DefaultCodec is the global default codec
|
// DefaultCodec is the global default codec
|
||||||
DefaultCodec Codec = NewCodec()
|
DefaultCodec Codec = NewCodec()
|
||||||
// DefaultTagName specifies struct tag name to control codec Marshal/Unmarshal
|
// DefaultTagName specifies struct tag name to control codec Marshal/Unmarshal
|
||||||
@@ -41,11 +41,11 @@ type MessageType int
|
|||||||
// connection. ReadBody may be called with a nil argument to force the
|
// connection. ReadBody may be called with a nil argument to force the
|
||||||
// body to be read and discarded.
|
// body to be read and discarded.
|
||||||
type Codec interface {
|
type Codec interface {
|
||||||
ReadHeader(io.Reader, *Message, MessageType) error
|
ReadHeader(r io.Reader, m *Message, mt MessageType) error
|
||||||
ReadBody(io.Reader, interface{}) error
|
ReadBody(r io.Reader, v interface{}) error
|
||||||
Write(io.Writer, *Message, interface{}) error
|
Write(w io.Writer, m *Message, v interface{}) error
|
||||||
Marshal(interface{}) ([]byte, error)
|
Marshal(v interface{}, opts ...Option) ([]byte, error)
|
||||||
Unmarshal([]byte, interface{}) error
|
Unmarshal(b []byte, v interface{}, opts ...Option) error
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ type Message struct {
|
|||||||
Method string
|
Method string
|
||||||
Endpoint string
|
Endpoint string
|
||||||
Error string
|
Error string
|
||||||
Id string
|
ID string
|
||||||
Body []byte
|
Body []byte
|
||||||
Type MessageType
|
Type MessageType
|
||||||
}
|
}
|
||||||
@@ -67,3 +67,20 @@ type Message struct {
|
|||||||
func NewMessage(t MessageType) *Message {
|
func NewMessage(t MessageType) *Message {
|
||||||
return &Message{Type: t, Header: metadata.New(0)}
|
return &Message{Type: t, Header: metadata.New(0)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalAppend calls codec.Marshal(v) and returns the data appended to buf.
|
||||||
|
// If codec implements MarshalAppend, that is called instead.
|
||||||
|
func MarshalAppend(buf []byte, c Codec, v interface{}, opts ...Option) ([]byte, error) {
|
||||||
|
if nc, ok := c.(interface {
|
||||||
|
MarshalAppend([]byte, interface{}, ...Option) ([]byte, error)
|
||||||
|
}); ok {
|
||||||
|
return nc.MarshalAppend(buf, v, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
mbuf, err := c.Marshal(v, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(buf, mbuf...), nil
|
||||||
|
}
|
||||||
|
34
codec/context.go
Normal file
34
codec/context.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package codec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type codecKey struct{}
|
||||||
|
|
||||||
|
// FromContext returns codec from context
|
||||||
|
func FromContext(ctx context.Context) (Codec, bool) {
|
||||||
|
if ctx == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
c, ok := ctx.Value(codecKey{}).(Codec)
|
||||||
|
return c, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContext put codec in context
|
||||||
|
func NewContext(ctx context.Context, c Codec) context.Context {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
return context.WithValue(ctx, codecKey{}, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOption returns a function to setup a context with given value
|
||||||
|
func SetOption(k, v interface{}) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
if o.Context == nil {
|
||||||
|
o.Context = context.Background()
|
||||||
|
}
|
||||||
|
o.Context = context.WithValue(o.Context, k, v)
|
||||||
|
}
|
||||||
|
}
|
@@ -4,3 +4,42 @@ package codec
|
|||||||
type Frame struct {
|
type Frame struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewFrame returns new frame with data
|
||||||
|
func NewFrame(data []byte) *Frame {
|
||||||
|
return &Frame{Data: data}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON returns frame data
|
||||||
|
func (m *Frame) MarshalJSON() ([]byte, error) {
|
||||||
|
return m.Marshal()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON set frame data
|
||||||
|
func (m *Frame) UnmarshalJSON(data []byte) error {
|
||||||
|
return m.Unmarshal(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtoMessage noop func
|
||||||
|
func (m *Frame) ProtoMessage() {}
|
||||||
|
|
||||||
|
// Reset resets frame
|
||||||
|
func (m *Frame) Reset() {
|
||||||
|
*m = Frame{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns frame as string
|
||||||
|
func (m *Frame) String() string {
|
||||||
|
return string(m.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal returns frame data
|
||||||
|
func (m *Frame) Marshal() ([]byte, error) {
|
||||||
|
return m.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal set frame data
|
||||||
|
func (m *Frame) Unmarshal(data []byte) error {
|
||||||
|
m.Data = data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -17,7 +17,7 @@ syntax = "proto3";
|
|||||||
package micro.codec;
|
package micro.codec;
|
||||||
|
|
||||||
option cc_enable_arenas = true;
|
option cc_enable_arenas = true;
|
||||||
option go_package = "github.com/unistack-org/micro/v3/codec;codec";
|
option go_package = "go.unistack.org/micro/v3/codec;codec";
|
||||||
option java_multiple_files = true;
|
option java_multiple_files = true;
|
||||||
option java_outer_classname = "MicroCodec";
|
option java_outer_classname = "MicroCodec";
|
||||||
option java_package = "micro.codec";
|
option java_package = "micro.codec";
|
||||||
|
@@ -5,7 +5,9 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
type noopCodec struct{}
|
type noopCodec struct {
|
||||||
|
opts Options
|
||||||
|
}
|
||||||
|
|
||||||
func (c *noopCodec) ReadHeader(conn io.Reader, m *Message, t MessageType) error {
|
func (c *noopCodec) ReadHeader(conn io.Reader, m *Message, t MessageType) error {
|
||||||
return nil
|
return nil
|
||||||
@@ -69,11 +71,11 @@ func (c *noopCodec) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCodec returns new noop codec
|
// NewCodec returns new noop codec
|
||||||
func NewCodec() Codec {
|
func NewCodec(opts ...Option) Codec {
|
||||||
return &noopCodec{}
|
return &noopCodec{opts: NewOptions(opts...)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *noopCodec) Marshal(v interface{}) ([]byte, error) {
|
func (c *noopCodec) Marshal(v interface{}, opts ...Option) ([]byte, error) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -96,7 +98,7 @@ func (c *noopCodec) Marshal(v interface{}) ([]byte, error) {
|
|||||||
return json.Marshal(v)
|
return json.Marshal(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *noopCodec) Unmarshal(d []byte, v interface{}) error {
|
func (c *noopCodec) Unmarshal(d []byte, v interface{}, opts ...Option) error {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
package codec
|
package codec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"context"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/logger"
|
||||||
|
"go.unistack.org/micro/v3/meter"
|
||||||
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Option func
|
// Option func
|
||||||
@@ -17,6 +19,10 @@ type Options struct {
|
|||||||
Logger logger.Logger
|
Logger logger.Logger
|
||||||
// Tracer used for tracing
|
// Tracer used for tracing
|
||||||
Tracer tracer.Tracer
|
Tracer tracer.Tracer
|
||||||
|
// Context stores additional codec options
|
||||||
|
Context context.Context
|
||||||
|
// TagName specifies tag name in struct to control codec
|
||||||
|
TagName string
|
||||||
// MaxMsgSize specifies max messages size that reads by codec
|
// MaxMsgSize specifies max messages size that reads by codec
|
||||||
MaxMsgSize int
|
MaxMsgSize int
|
||||||
}
|
}
|
||||||
@@ -28,6 +34,13 @@ func MaxMsgSize(n int) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TagName sets the codec tag name in struct
|
||||||
|
func TagName(n string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.TagName = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Logger sets the logger
|
// Logger sets the logger
|
||||||
func Logger(l logger.Logger) Option {
|
func Logger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
@@ -52,10 +65,12 @@ func Meter(m meter.Meter) Option {
|
|||||||
// NewOptions returns new options
|
// NewOptions returns new options
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
options := Options{
|
options := Options{
|
||||||
|
Context: context.Background(),
|
||||||
Logger: logger.DefaultLogger,
|
Logger: logger.DefaultLogger,
|
||||||
Meter: meter.DefaultMeter,
|
Meter: meter.DefaultMeter,
|
||||||
Tracer: tracer.DefaultTracer,
|
Tracer: tracer.DefaultTracer,
|
||||||
MaxMsgSize: DefaultMaxMsgSize,
|
MaxMsgSize: DefaultMaxMsgSize,
|
||||||
|
TagName: DefaultTagName,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package config is an interface for dynamic configuration.
|
// Package config is an interface for dynamic configuration.
|
||||||
package config
|
package config // import "go.unistack.org/micro/v3/config"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -13,7 +13,7 @@ var DefaultConfig Config = NewConfig()
|
|||||||
// DefaultWatcherMinInterval default min interval for poll changes
|
// DefaultWatcherMinInterval default min interval for poll changes
|
||||||
var DefaultWatcherMinInterval = 5 * time.Second
|
var DefaultWatcherMinInterval = 5 * time.Second
|
||||||
|
|
||||||
// DefaultWatcherMinInterval default max interval for poll changes
|
// DefaultWatcherMaxInterval default max interval for poll changes
|
||||||
var DefaultWatcherMaxInterval = 9 * time.Second
|
var DefaultWatcherMaxInterval = 9 * time.Second
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -23,6 +23,8 @@ var (
|
|||||||
ErrInvalidStruct = errors.New("invalid struct specified")
|
ErrInvalidStruct = errors.New("invalid struct specified")
|
||||||
// ErrWatcherStopped is returned when source watcher has been stopped
|
// ErrWatcherStopped is returned when source watcher has been stopped
|
||||||
ErrWatcherStopped = errors.New("watcher stopped")
|
ErrWatcherStopped = errors.New("watcher stopped")
|
||||||
|
// ErrWatcherNotImplemented returned when config does not implement watch
|
||||||
|
ErrWatcherNotImplemented = errors.New("watcher not implemented")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is an interface abstraction for dynamic configuration
|
// Config is an interface abstraction for dynamic configuration
|
||||||
@@ -64,3 +66,53 @@ func Load(ctx context.Context, cs []Config, opts ...LoadOption) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefaultAfterLoad = func(ctx context.Context, c Config) error {
|
||||||
|
for _, fn := range c.Options().AfterLoad {
|
||||||
|
if err := fn(ctx, c); err != nil {
|
||||||
|
c.Options().Logger.Errorf(ctx, "%s AfterLoad err: %v", c.String(), err)
|
||||||
|
if !c.Options().AllowFail {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultAfterSave = func(ctx context.Context, c Config) error {
|
||||||
|
for _, fn := range c.Options().AfterSave {
|
||||||
|
if err := fn(ctx, c); err != nil {
|
||||||
|
c.Options().Logger.Errorf(ctx, "%s AfterSave err: %v", c.String(), err)
|
||||||
|
if !c.Options().AllowFail {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultBeforeLoad = func(ctx context.Context, c Config) error {
|
||||||
|
for _, fn := range c.Options().BeforeLoad {
|
||||||
|
if err := fn(ctx, c); err != nil {
|
||||||
|
c.Options().Logger.Errorf(ctx, "%s BeforeLoad err: %v", c.String(), err)
|
||||||
|
if !c.Options().AllowFail {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultBeforeSave = func(ctx context.Context, c Config) error {
|
||||||
|
for _, fn := range c.Options().BeforeSave {
|
||||||
|
if err := fn(ctx, c); err != nil {
|
||||||
|
c.Options().Logger.Errorf(ctx, "%s BeforeSavec err: %v", c.String(), err)
|
||||||
|
if !c.Options().AllowFail {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@@ -32,3 +32,33 @@ func SetOption(k, v interface{}) Option {
|
|||||||
o.Context = context.WithValue(o.Context, k, v)
|
o.Context = context.WithValue(o.Context, k, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSaveOption returns a function to setup a context with given value
|
||||||
|
func SetSaveOption(k, v interface{}) SaveOption {
|
||||||
|
return func(o *SaveOptions) {
|
||||||
|
if o.Context == nil {
|
||||||
|
o.Context = context.Background()
|
||||||
|
}
|
||||||
|
o.Context = context.WithValue(o.Context, k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLoadOption returns a function to setup a context with given value
|
||||||
|
func SetLoadOption(k, v interface{}) LoadOption {
|
||||||
|
return func(o *LoadOptions) {
|
||||||
|
if o.Context == nil {
|
||||||
|
o.Context = context.Background()
|
||||||
|
}
|
||||||
|
o.Context = context.WithValue(o.Context, k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWatchOption returns a function to setup a context with given value
|
||||||
|
func SetWatchOption(k, v interface{}) WatchOption {
|
||||||
|
return func(o *WatchOptions) {
|
||||||
|
if o.Context == nil {
|
||||||
|
o.Context = context.Background()
|
||||||
|
}
|
||||||
|
o.Context = context.WithValue(o.Context, k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2,13 +2,12 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
rutil "github.com/unistack-org/micro/v3/util/reflect"
|
rutil "go.unistack.org/micro/v3/util/reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type defaultConfig struct {
|
type defaultConfig struct {
|
||||||
@@ -27,10 +26,8 @@ func (c *defaultConfig) Init(opts ...Option) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *defaultConfig) Load(ctx context.Context, opts ...LoadOption) error {
|
func (c *defaultConfig) Load(ctx context.Context, opts ...LoadOption) error {
|
||||||
for _, fn := range c.opts.BeforeLoad {
|
if err := DefaultBeforeLoad(ctx, c); err != nil {
|
||||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options := NewLoadOptions(opts...)
|
options := NewLoadOptions(opts...)
|
||||||
@@ -48,20 +45,26 @@ func (c *defaultConfig) Load(ctx context.Context, opts ...LoadOption) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
src, err := rutil.Zero(dst)
|
src, err := rutil.Zero(dst)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
if err = fillValues(reflect.ValueOf(src), c.opts.StructTag); err == nil {
|
if !c.opts.AllowFail {
|
||||||
err = mergo.Merge(dst, src, mopts...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil && !c.opts.AllowFail {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, fn := range c.opts.AfterLoad {
|
|
||||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return DefaultAfterLoad(ctx, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = fillValues(reflect.ValueOf(src), c.opts.StructTag); err == nil {
|
||||||
|
err = mergo.Merge(dst, src, mopts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.opts.Logger.Errorf(ctx, "default load error: %v", err)
|
||||||
|
if !c.opts.AllowFail {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DefaultAfterLoad(ctx, c); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -247,16 +250,12 @@ func fillValues(valueOf reflect.Value, tname string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *defaultConfig) Save(ctx context.Context, opts ...SaveOption) error {
|
func (c *defaultConfig) Save(ctx context.Context, opts ...SaveOption) error {
|
||||||
for _, fn := range c.opts.BeforeSave {
|
if err := DefaultBeforeSave(ctx, c); err != nil {
|
||||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fn := range c.opts.AfterSave {
|
if err := DefaultAfterSave(ctx, c); err != nil {
|
||||||
if err := fn(ctx, c); err != nil && !c.opts.AllowFail {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -271,7 +270,7 @@ func (c *defaultConfig) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *defaultConfig) Watch(ctx context.Context, opts ...WatchOption) (Watcher, error) {
|
func (c *defaultConfig) Watch(ctx context.Context, opts ...WatchOption) (Watcher, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, ErrWatcherNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfig returns new default config source
|
// NewConfig returns new default config source
|
||||||
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/config"
|
"go.unistack.org/micro/v3/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cfg struct {
|
type Cfg struct {
|
||||||
@@ -48,5 +48,5 @@ func TestDefault(t *testing.T) {
|
|||||||
t.Fatal("AfterLoad option not working")
|
t.Fatal("AfterLoad option not working")
|
||||||
}
|
}
|
||||||
_ = conf
|
_ = conf
|
||||||
//t.Logf("%#+v\n", conf)
|
// t.Logf("%#+v\n", conf)
|
||||||
}
|
}
|
||||||
|
@@ -4,10 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options hold the config options
|
// Options hold the config options
|
||||||
@@ -66,6 +66,7 @@ type LoadOptions struct {
|
|||||||
Struct interface{}
|
Struct interface{}
|
||||||
Override bool
|
Override bool
|
||||||
Append bool
|
Append bool
|
||||||
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLoadOptions(opts ...LoadOption) LoadOptions {
|
func NewLoadOptions(opts ...LoadOption) LoadOptions {
|
||||||
@@ -102,7 +103,8 @@ type SaveOption func(o *SaveOptions)
|
|||||||
|
|
||||||
// SaveOptions struct
|
// SaveOptions struct
|
||||||
type SaveOptions struct {
|
type SaveOptions struct {
|
||||||
Struct interface{}
|
Struct interface{}
|
||||||
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveStruct override struct for save to config
|
// SaveStruct override struct for save to config
|
||||||
@@ -209,14 +211,14 @@ func Name(n string) Option {
|
|||||||
type WatchOptions struct {
|
type WatchOptions struct {
|
||||||
// Context used by non default options
|
// Context used by non default options
|
||||||
Context context.Context
|
Context context.Context
|
||||||
// Coalesce multiple events to one
|
// Struct for filling
|
||||||
Coalesce bool
|
Struct interface{}
|
||||||
// MinInterval specifies the min time.Duration interval for poll changes
|
// MinInterval specifies the min time.Duration interval for poll changes
|
||||||
MinInterval time.Duration
|
MinInterval time.Duration
|
||||||
// MaxInterval specifies the max time.Duration interval for poll changes
|
// MaxInterval specifies the max time.Duration interval for poll changes
|
||||||
MaxInterval time.Duration
|
MaxInterval time.Duration
|
||||||
// Struct for filling
|
// Coalesce multiple events to one
|
||||||
Struct interface{}
|
Coalesce bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type WatchOption func(*WatchOptions)
|
type WatchOption func(*WatchOptions)
|
||||||
|
183
errors/errors.go
183
errors/errors.go
@@ -1,11 +1,14 @@
|
|||||||
// Package errors provides a way to return detailed information
|
// Package errors provides a way to return detailed information
|
||||||
// for an RPC request error. The error is normally JSON encoded.
|
// for an RPC request error. The error is normally JSON encoded.
|
||||||
package errors
|
package errors // import "go.unistack.org/micro/v3/errors"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -37,8 +40,8 @@ var (
|
|||||||
|
|
||||||
// Error type
|
// Error type
|
||||||
type Error struct {
|
type Error struct {
|
||||||
// Id holds error id or service, usually someting like my_service or id
|
// ID holds error id or service, usually someting like my_service or id
|
||||||
Id string
|
ID string
|
||||||
// Detail holds some useful details about error
|
// Detail holds some useful details about error
|
||||||
Detail string
|
Detail string
|
||||||
// Status usually holds text of http status
|
// Status usually holds text of http status
|
||||||
@@ -53,10 +56,26 @@ func (e *Error) Error() string {
|
|||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Generator struct holds id of error
|
||||||
|
type Generator struct {
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generator can emit new error with static id
|
||||||
|
func NewGenerator(id string) *Generator {
|
||||||
|
return &Generator{id: id}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) BadRequest(format string, args ...interface{}) error {
|
||||||
|
return BadRequest(g.id, format, args...)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// New generates a custom error
|
// New generates a custom error
|
||||||
func New(id, detail string, code int32) error {
|
func New(id, detail string, code int32) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: code,
|
Code: code,
|
||||||
Detail: detail,
|
Detail: detail,
|
||||||
Status: http.StatusText(int(code)),
|
Status: http.StatusText(int(code)),
|
||||||
@@ -66,130 +85,130 @@ func New(id, detail string, code int32) error {
|
|||||||
// Parse tries to parse a JSON string into an error. If that
|
// Parse tries to parse a JSON string into an error. If that
|
||||||
// fails, it will set the given string as the error detail.
|
// fails, it will set the given string as the error detail.
|
||||||
func Parse(err string) *Error {
|
func Parse(err string) *Error {
|
||||||
e := new(Error)
|
e := &Error{}
|
||||||
errr := json.Unmarshal([]byte(err), e)
|
nerr := json.Unmarshal([]byte(err), e)
|
||||||
if errr != nil {
|
if nerr != nil {
|
||||||
e.Detail = err
|
e.Detail = err
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// BadRequest generates a 400 error.
|
// BadRequest generates a 400 error.
|
||||||
func BadRequest(id, format string, a ...interface{}) error {
|
func BadRequest(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 400,
|
Code: 400,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(400),
|
Status: http.StatusText(400),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unauthorized generates a 401 error.
|
// Unauthorized generates a 401 error.
|
||||||
func Unauthorized(id, format string, a ...interface{}) error {
|
func Unauthorized(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 401,
|
Code: 401,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(401),
|
Status: http.StatusText(401),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forbidden generates a 403 error.
|
// Forbidden generates a 403 error.
|
||||||
func Forbidden(id, format string, a ...interface{}) error {
|
func Forbidden(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 403,
|
Code: 403,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(403),
|
Status: http.StatusText(403),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotFound generates a 404 error.
|
// NotFound generates a 404 error.
|
||||||
func NotFound(id, format string, a ...interface{}) error {
|
func NotFound(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 404,
|
Code: 404,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(404),
|
Status: http.StatusText(404),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MethodNotAllowed generates a 405 error.
|
// MethodNotAllowed generates a 405 error.
|
||||||
func MethodNotAllowed(id, format string, a ...interface{}) error {
|
func MethodNotAllowed(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 405,
|
Code: 405,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(405),
|
Status: http.StatusText(405),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout generates a 408 error.
|
// Timeout generates a 408 error.
|
||||||
func Timeout(id, format string, a ...interface{}) error {
|
func Timeout(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 408,
|
Code: 408,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(408),
|
Status: http.StatusText(408),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conflict generates a 409 error.
|
// Conflict generates a 409 error.
|
||||||
func Conflict(id, format string, a ...interface{}) error {
|
func Conflict(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 409,
|
Code: 409,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(409),
|
Status: http.StatusText(409),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InternalServerError generates a 500 error.
|
// InternalServerError generates a 500 error.
|
||||||
func InternalServerError(id, format string, a ...interface{}) error {
|
func InternalServerError(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 500,
|
Code: 500,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(500),
|
Status: http.StatusText(500),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotImplemented generates a 501 error
|
// NotImplemented generates a 501 error
|
||||||
func NotImplemented(id, format string, a ...interface{}) error {
|
func NotImplemented(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 501,
|
Code: 501,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(501),
|
Status: http.StatusText(501),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BadGateway generates a 502 error
|
// BadGateway generates a 502 error
|
||||||
func BadGateway(id, format string, a ...interface{}) error {
|
func BadGateway(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 502,
|
Code: 502,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(502),
|
Status: http.StatusText(502),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceUnavailable generates a 503 error
|
// ServiceUnavailable generates a 503 error
|
||||||
func ServiceUnavailable(id, format string, a ...interface{}) error {
|
func ServiceUnavailable(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 503,
|
Code: 503,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(503),
|
Status: http.StatusText(503),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GatewayTimeout generates a 504 error
|
// GatewayTimeout generates a 504 error
|
||||||
func GatewayTimeout(id, format string, a ...interface{}) error {
|
func GatewayTimeout(id, format string, args ...interface{}) error {
|
||||||
return &Error{
|
return &Error{
|
||||||
Id: id,
|
ID: id,
|
||||||
Code: 504,
|
Code: 504,
|
||||||
Detail: fmt.Sprintf(format, a...),
|
Detail: fmt.Sprintf(format, args...),
|
||||||
Status: http.StatusText(504),
|
Status: http.StatusText(504),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,3 +241,81 @@ func FromError(err error) *Error {
|
|||||||
|
|
||||||
return Parse(err.Error())
|
return Parse(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON returns error data
|
||||||
|
func (e *Error) MarshalJSON() ([]byte, error) {
|
||||||
|
return e.Marshal()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON set error data
|
||||||
|
func (e *Error) UnmarshalJSON(data []byte) error {
|
||||||
|
return e.Unmarshal(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtoMessage noop func
|
||||||
|
func (e *Error) ProtoMessage() {}
|
||||||
|
|
||||||
|
// Reset resets error
|
||||||
|
func (e *Error) Reset() {
|
||||||
|
*e = Error{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns error as string
|
||||||
|
func (e *Error) String() string {
|
||||||
|
return fmt.Sprintf(`{"id":"%s","detail":"%s","status":"%s","code":%d}`, addslashes(e.ID), addslashes(e.Detail), addslashes(e.Status), e.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal returns error data
|
||||||
|
func (e *Error) Marshal() ([]byte, error) {
|
||||||
|
return []byte(e.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal set error data
|
||||||
|
func (e *Error) Unmarshal(data []byte) error {
|
||||||
|
str := string(data)
|
||||||
|
if len(data) < 41 {
|
||||||
|
return fmt.Errorf("invalid data")
|
||||||
|
}
|
||||||
|
parts := strings.FieldsFunc(str[1:len(str)-1], func(r rune) bool {
|
||||||
|
return r == ','
|
||||||
|
})
|
||||||
|
for _, part := range parts {
|
||||||
|
nparts := strings.FieldsFunc(part, func(r rune) bool {
|
||||||
|
return r == ':'
|
||||||
|
})
|
||||||
|
for idx := 0; idx < len(nparts)/2; idx += 2 {
|
||||||
|
val := strings.Trim(nparts[idx+1], `"`)
|
||||||
|
if len(val) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case nparts[idx] == `"id"`:
|
||||||
|
e.ID = val
|
||||||
|
case nparts[idx] == `"detail"`:
|
||||||
|
e.Detail = val
|
||||||
|
case nparts[idx] == `"status"`:
|
||||||
|
e.Status = val
|
||||||
|
case nparts[idx] == `"code"`:
|
||||||
|
c, err := strconv.ParseInt(val, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
e.Code = int32(c)
|
||||||
|
}
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addslashes(str string) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for _, char := range str {
|
||||||
|
switch char {
|
||||||
|
case '\'', '"', '\\':
|
||||||
|
buf.WriteRune('\\')
|
||||||
|
}
|
||||||
|
buf.WriteRune(char)
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
31
errors/errors.proto
Normal file
31
errors/errors.proto
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2021 Unistack LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package micro.errors;
|
||||||
|
|
||||||
|
option cc_enable_arenas = true;
|
||||||
|
option go_package = "go.unistack.org/micro/v3/errors;errors";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_outer_classname = "MicroErrors";
|
||||||
|
option java_package = "micro.errors";
|
||||||
|
option objc_class_prefix = "MERRORS";
|
||||||
|
|
||||||
|
message Error {
|
||||||
|
string id = 1;
|
||||||
|
string detail = 2;
|
||||||
|
string status = 3;
|
||||||
|
uint32 code = 4;
|
||||||
|
}
|
@@ -1,20 +1,43 @@
|
|||||||
package errors
|
package errors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
er "errors"
|
er "errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestMarshalJSON(t *testing.T) {
|
||||||
|
e := InternalServerError("id", "err: %v", fmt.Errorf("err: %v", `xxx: "UNIX_TIMESTAMP": invalid identifier`))
|
||||||
|
_, err := json.Marshal(e)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEmpty(t *testing.T) {
|
||||||
|
msg := "test"
|
||||||
|
var err *Error
|
||||||
|
err = FromError(fmt.Errorf(msg))
|
||||||
|
if err.Detail != msg {
|
||||||
|
t.Fatalf("invalid error %v", err)
|
||||||
|
}
|
||||||
|
err = FromError(fmt.Errorf(`{"id":"","detail":"%s","status":"%s","code":0}`, msg, msg))
|
||||||
|
if err.Detail != msg || err.Status != msg {
|
||||||
|
t.Fatalf("invalid error %#+v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFromError(t *testing.T) {
|
func TestFromError(t *testing.T) {
|
||||||
err := NotFound("go.micro.test", "%s", "example")
|
err := NotFound("go.micro.test", "%s", "example")
|
||||||
merr := FromError(err)
|
merr := FromError(err)
|
||||||
if merr.Id != "go.micro.test" || merr.Code != 404 {
|
if merr.ID != "go.micro.test" || merr.Code != 404 {
|
||||||
t.Fatalf("invalid conversation %v != %v", err, merr)
|
t.Fatalf("invalid conversation %v != %v", err, merr)
|
||||||
}
|
}
|
||||||
err = er.New(err.Error())
|
err = er.New(err.Error())
|
||||||
merr = FromError(err)
|
merr = FromError(err)
|
||||||
if merr.Id != "go.micro.test" || merr.Code != 404 {
|
if merr.ID != "go.micro.test" || merr.Code != 404 {
|
||||||
t.Fatalf("invalid conversation %v != %v", err, merr)
|
t.Fatalf("invalid conversation %v != %v", err, merr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +59,7 @@ func TestEqual(t *testing.T) {
|
|||||||
func TestErrors(t *testing.T) {
|
func TestErrors(t *testing.T) {
|
||||||
testData := []*Error{
|
testData := []*Error{
|
||||||
{
|
{
|
||||||
Id: "test",
|
ID: "test",
|
||||||
Code: 500,
|
Code: 500,
|
||||||
Detail: "Internal server error",
|
Detail: "Internal server error",
|
||||||
Status: http.StatusText(500),
|
Status: http.StatusText(500),
|
||||||
@@ -44,7 +67,7 @@ func TestErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range testData {
|
for _, e := range testData {
|
||||||
ne := New(e.Id, e.Detail, e.Code)
|
ne := New(e.ID, e.Detail, e.Code)
|
||||||
|
|
||||||
if e.Error() != ne.Error() {
|
if e.Error() != ne.Error() {
|
||||||
t.Fatalf("Expected %s got %s", e.Error(), ne.Error())
|
t.Fatalf("Expected %s got %s", e.Error(), ne.Error())
|
||||||
@@ -56,8 +79,8 @@ func TestErrors(t *testing.T) {
|
|||||||
t.Fatalf("Expected error got nil %v", pe)
|
t.Fatalf("Expected error got nil %v", pe)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pe.Id != e.Id {
|
if pe.ID != e.ID {
|
||||||
t.Fatalf("Expected %s got %s", e.Id, pe.Id)
|
t.Fatalf("Expected %s got %s", e.ID, pe.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pe.Detail != e.Detail {
|
if pe.Detail != e.Detail {
|
||||||
|
2
event.go
2
event.go
@@ -3,7 +3,7 @@ package micro
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Event is used to publish messages to a topic
|
// Event is used to publish messages to a topic
|
||||||
|
@@ -7,12 +7,12 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/silas/dag"
|
"github.com/silas/dag"
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
"github.com/unistack-org/micro/v3/store"
|
"go.unistack.org/micro/v3/store"
|
||||||
"github.com/unistack-org/micro/v3/util/id"
|
"go.unistack.org/micro/v3/util/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type microFlow struct {
|
type microFlow struct {
|
||||||
@@ -20,13 +20,13 @@ type microFlow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type microWorkflow struct {
|
type microWorkflow struct {
|
||||||
id string
|
|
||||||
g *dag.AcyclicGraph
|
|
||||||
init bool
|
|
||||||
sync.RWMutex
|
|
||||||
opts Options
|
opts Options
|
||||||
|
g *dag.AcyclicGraph
|
||||||
steps map[string]Step
|
steps map[string]Step
|
||||||
|
id string
|
||||||
status Status
|
status Status
|
||||||
|
sync.RWMutex
|
||||||
|
init bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *microWorkflow) ID() string {
|
func (w *microWorkflow) ID() string {
|
||||||
@@ -241,6 +241,7 @@ func (w *microWorkflow) Execute(ctx context.Context, req *Message, opts ...Execu
|
|||||||
w.opts.Logger.Tracef(nctx, "will be executed %v", steps[idx][nidx])
|
w.opts.Logger.Tracef(nctx, "will be executed %v", steps[idx][nidx])
|
||||||
}
|
}
|
||||||
cstep := steps[idx][nidx]
|
cstep := steps[idx][nidx]
|
||||||
|
// nolint: nestif
|
||||||
if len(cstep.Requires()) == 0 {
|
if len(cstep.Requires()) == 0 {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(step Step) {
|
go func(step Step) {
|
||||||
@@ -264,17 +265,16 @@ func (w *microWorkflow) Execute(ctx context.Context, req *Message, opts ...Execu
|
|||||||
}
|
}
|
||||||
cherr <- serr
|
cherr <- serr
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
if werr := stepStore.Write(ctx, filepath.Join(step.ID(), "rsp"), rsp); werr != nil {
|
if werr := stepStore.Write(ctx, filepath.Join(step.ID(), "rsp"), rsp); werr != nil {
|
||||||
w.opts.Logger.Errorf(ctx, "store write error: %v", werr)
|
w.opts.Logger.Errorf(ctx, "store write error: %v", werr)
|
||||||
cherr <- werr
|
cherr <- werr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if werr := stepStore.Write(ctx, filepath.Join(step.ID(), "status"), &codec.Frame{Data: []byte(StatusSuccess.String())}); werr != nil {
|
if werr := stepStore.Write(ctx, filepath.Join(step.ID(), "status"), &codec.Frame{Data: []byte(StatusSuccess.String())}); werr != nil {
|
||||||
w.opts.Logger.Errorf(ctx, "store write error: %v", werr)
|
w.opts.Logger.Errorf(ctx, "store write error: %v", werr)
|
||||||
cherr <- werr
|
cherr <- werr
|
||||||
return
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}(cstep)
|
}(cstep)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@@ -298,16 +298,15 @@ func (w *microWorkflow) Execute(ctx context.Context, req *Message, opts ...Execu
|
|||||||
}
|
}
|
||||||
cherr <- serr
|
cherr <- serr
|
||||||
return
|
return
|
||||||
} else {
|
}
|
||||||
if werr := stepStore.Write(ctx, filepath.Join(cstep.ID(), "rsp"), rsp); werr != nil {
|
if werr := stepStore.Write(ctx, filepath.Join(cstep.ID(), "rsp"), rsp); werr != nil {
|
||||||
w.opts.Logger.Errorf(ctx, "store write error: %v", werr)
|
w.opts.Logger.Errorf(ctx, "store write error: %v", werr)
|
||||||
cherr <- werr
|
cherr <- werr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if werr := stepStore.Write(ctx, filepath.Join(cstep.ID(), "status"), &codec.Frame{Data: []byte(StatusSuccess.String())}); werr != nil {
|
if werr := stepStore.Write(ctx, filepath.Join(cstep.ID(), "status"), &codec.Frame{Data: []byte(StatusSuccess.String())}); werr != nil {
|
||||||
cherr <- werr
|
cherr <- werr
|
||||||
return
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,22 +336,20 @@ func (w *microWorkflow) Execute(ctx context.Context, req *Message, opts ...Execu
|
|||||||
if werr := workflowStore.Write(w.opts.Context, "status", &codec.Frame{Data: []byte(StatusAborted.String())}); werr != nil {
|
if werr := workflowStore.Write(w.opts.Context, "status", &codec.Frame{Data: []byte(StatusAborted.String())}); werr != nil {
|
||||||
w.opts.Logger.Errorf(w.opts.Context, "store error: %v", werr)
|
w.opts.Logger.Errorf(w.opts.Context, "store error: %v", werr)
|
||||||
}
|
}
|
||||||
break
|
|
||||||
case err == nil:
|
case err == nil:
|
||||||
if werr := workflowStore.Write(w.opts.Context, "status", &codec.Frame{Data: []byte(StatusSuccess.String())}); werr != nil {
|
if werr := workflowStore.Write(w.opts.Context, "status", &codec.Frame{Data: []byte(StatusSuccess.String())}); werr != nil {
|
||||||
w.opts.Logger.Errorf(w.opts.Context, "store error: %v", werr)
|
w.opts.Logger.Errorf(w.opts.Context, "store error: %v", werr)
|
||||||
}
|
}
|
||||||
break
|
|
||||||
case err != nil:
|
case err != nil:
|
||||||
if werr := workflowStore.Write(w.opts.Context, "status", &codec.Frame{Data: []byte(StatusFailure.String())}); werr != nil {
|
if werr := workflowStore.Write(w.opts.Context, "status", &codec.Frame{Data: []byte(StatusFailure.String())}); werr != nil {
|
||||||
w.opts.Logger.Errorf(w.opts.Context, "store error: %v", werr)
|
w.opts.Logger.Errorf(w.opts.Context, "store error: %v", werr)
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return eid, err
|
return eid, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewFlow create new flow
|
||||||
func NewFlow(opts ...Option) Flow {
|
func NewFlow(opts ...Option) Flow {
|
||||||
options := NewOptions(opts...)
|
options := NewOptions(opts...)
|
||||||
return µFlow{opts: options}
|
return µFlow{opts: options}
|
||||||
@@ -429,11 +426,11 @@ func (f *microFlow) WorkflowLoad(ctx context.Context, id string) (Workflow, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
type microCallStep struct {
|
type microCallStep struct {
|
||||||
opts StepOptions
|
|
||||||
service string
|
|
||||||
method string
|
|
||||||
rsp *Message
|
rsp *Message
|
||||||
req *Message
|
req *Message
|
||||||
|
service string
|
||||||
|
method string
|
||||||
|
opts StepOptions
|
||||||
status Status
|
status Status
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,10 +496,12 @@ func (s *microCallStep) Execute(ctx context.Context, req *Message, opts ...Execu
|
|||||||
rsp := &codec.Frame{}
|
rsp := &codec.Frame{}
|
||||||
copts := []client.CallOption{client.WithRetries(0)}
|
copts := []client.CallOption{client.WithRetries(0)}
|
||||||
if options.Timeout > 0 {
|
if options.Timeout > 0 {
|
||||||
copts = append(copts, client.WithRequestTimeout(options.Timeout), client.WithDialTimeout(options.Timeout))
|
copts = append(copts,
|
||||||
|
client.WithRequestTimeout(options.Timeout),
|
||||||
|
client.WithDialTimeout(options.Timeout))
|
||||||
}
|
}
|
||||||
nctx := metadata.NewOutgoingContext(ctx, req.Header)
|
nctx := metadata.NewOutgoingContext(ctx, req.Header)
|
||||||
err := options.Client.Call(nctx, options.Client.NewRequest(s.service, s.method, &codec.Frame{Data: req.Body}), rsp)
|
err := options.Client.Call(nctx, options.Client.NewRequest(s.service, s.method, &codec.Frame{Data: req.Body}), rsp, copts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -511,10 +510,10 @@ func (s *microCallStep) Execute(ctx context.Context, req *Message, opts ...Execu
|
|||||||
}
|
}
|
||||||
|
|
||||||
type microPublishStep struct {
|
type microPublishStep struct {
|
||||||
opts StepOptions
|
|
||||||
topic string
|
|
||||||
req *Message
|
req *Message
|
||||||
rsp *Message
|
rsp *Message
|
||||||
|
topic string
|
||||||
|
opts StepOptions
|
||||||
status Status
|
status Status
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,7 +552,7 @@ func (s *microPublishStep) String() string {
|
|||||||
if s.opts.ID != "" {
|
if s.opts.ID != "" {
|
||||||
return s.opts.ID
|
return s.opts.ID
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s", s.topic)
|
return s.topic
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *microPublishStep) Name() string {
|
func (s *microPublishStep) Name() string {
|
||||||
@@ -576,11 +575,13 @@ func (s *microPublishStep) Execute(ctx context.Context, req *Message, opts ...Ex
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewCallStep create new step with client.Call
|
||||||
func NewCallStep(service string, name string, method string, opts ...StepOption) Step {
|
func NewCallStep(service string, name string, method string, opts ...StepOption) Step {
|
||||||
options := NewStepOptions(opts...)
|
options := NewStepOptions(opts...)
|
||||||
return µCallStep{service: service, method: name + "." + method, opts: options}
|
return µCallStep{service: service, method: name + "." + method, opts: options}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPublishStep create new step with client.Publish
|
||||||
func NewPublishStep(topic string, opts ...StepOption) Step {
|
func NewPublishStep(topic string, opts ...StepOption) Step {
|
||||||
options := NewStepOptions(opts...)
|
options := NewStepOptions(opts...)
|
||||||
return µPublishStep{topic: topic, opts: options}
|
return µPublishStep{topic: topic, opts: options}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package flow is an interface used for saga pattern microservice workflow
|
// Package flow is an interface used for saga pattern microservice workflow
|
||||||
package flow
|
package flow // import "go.unistack.org/micro/v3/flow"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/store"
|
"go.unistack.org/micro/v3/store"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Option func
|
// Option func
|
||||||
@@ -70,7 +70,7 @@ func Client(c client.Client) Option {
|
|||||||
|
|
||||||
// Context specifies a context for the service.
|
// Context specifies a context for the service.
|
||||||
// Can be used to signal shutdown of the flow
|
// Can be used to signal shutdown of the flow
|
||||||
// Can be used for extra option values.
|
// or can be used for extra option values.
|
||||||
func Context(ctx context.Context) Option {
|
func Context(ctx context.Context) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Context = ctx
|
o.Context = ctx
|
||||||
@@ -91,13 +91,13 @@ func Store(s store.Store) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorflowOption signature
|
// WorflowOption func signature
|
||||||
type WorkflowOption func(*WorkflowOptions)
|
type WorkflowOption func(*WorkflowOptions)
|
||||||
|
|
||||||
// WorkflowOptions holds workflow options
|
// WorkflowOptions holds workflow options
|
||||||
type WorkflowOptions struct {
|
type WorkflowOptions struct {
|
||||||
ID string
|
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
ID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// WorkflowID set workflow id
|
// WorkflowID set workflow id
|
||||||
@@ -107,6 +107,7 @@ func WorkflowID(id string) WorkflowOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteOptions holds execute options
|
||||||
type ExecuteOptions struct {
|
type ExecuteOptions struct {
|
||||||
// Client holds the client.Client
|
// Client holds the client.Client
|
||||||
Client client.Client
|
Client client.Client
|
||||||
@@ -120,64 +121,74 @@ type ExecuteOptions struct {
|
|||||||
Context context.Context
|
Context context.Context
|
||||||
// Start step
|
// Start step
|
||||||
Start string
|
Start string
|
||||||
// Reverse execution
|
|
||||||
Reverse bool
|
|
||||||
// Timeout for execution
|
// Timeout for execution
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
|
// Reverse execution
|
||||||
|
Reverse bool
|
||||||
// Async enables async execution
|
// Async enables async execution
|
||||||
Async bool
|
Async bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteOption func signature
|
||||||
type ExecuteOption func(*ExecuteOptions)
|
type ExecuteOption func(*ExecuteOptions)
|
||||||
|
|
||||||
|
// ExecuteClient pass client.Client to ExecuteOption
|
||||||
func ExecuteClient(c client.Client) ExecuteOption {
|
func ExecuteClient(c client.Client) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Client = c
|
o.Client = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteTracer pass tracer.Tracer to ExecuteOption
|
||||||
func ExecuteTracer(t tracer.Tracer) ExecuteOption {
|
func ExecuteTracer(t tracer.Tracer) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Tracer = t
|
o.Tracer = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteLogger pass logger.Logger to ExecuteOption
|
||||||
func ExecuteLogger(l logger.Logger) ExecuteOption {
|
func ExecuteLogger(l logger.Logger) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteMeter pass meter.Meter to ExecuteOption
|
||||||
func ExecuteMeter(m meter.Meter) ExecuteOption {
|
func ExecuteMeter(m meter.Meter) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Meter = m
|
o.Meter = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteContext pass context.Context ot ExecuteOption
|
||||||
func ExecuteContext(ctx context.Context) ExecuteOption {
|
func ExecuteContext(ctx context.Context) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Context = ctx
|
o.Context = ctx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteReverse says that dag must be run in reverse order
|
||||||
func ExecuteReverse(b bool) ExecuteOption {
|
func ExecuteReverse(b bool) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Reverse = b
|
o.Reverse = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteTimeout pass timeout time.Duration for execution
|
||||||
func ExecuteTimeout(td time.Duration) ExecuteOption {
|
func ExecuteTimeout(td time.Duration) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Timeout = td
|
o.Timeout = td
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteAsync says that caller does not wait for execution complete
|
||||||
func ExecuteAsync(b bool) ExecuteOption {
|
func ExecuteAsync(b bool) ExecuteOption {
|
||||||
return func(o *ExecuteOptions) {
|
return func(o *ExecuteOptions) {
|
||||||
o.Async = b
|
o.Async = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewExecuteOptions create new ExecuteOptions struct
|
||||||
func NewExecuteOptions(opts ...ExecuteOption) ExecuteOptions {
|
func NewExecuteOptions(opts ...ExecuteOption) ExecuteOptions {
|
||||||
options := ExecuteOptions{
|
options := ExecuteOptions{
|
||||||
Client: client.DefaultClient,
|
Client: client.DefaultClient,
|
||||||
@@ -192,15 +203,18 @@ func NewExecuteOptions(opts ...ExecuteOption) ExecuteOptions {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StepOptions holds step options
|
||||||
type StepOptions struct {
|
type StepOptions struct {
|
||||||
ID string
|
|
||||||
Context context.Context
|
Context context.Context
|
||||||
Requires []string
|
|
||||||
Fallback string
|
Fallback string
|
||||||
|
ID string
|
||||||
|
Requires []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StepOption func signature
|
||||||
type StepOption func(*StepOptions)
|
type StepOption func(*StepOptions)
|
||||||
|
|
||||||
|
// NewStepOptions create new StepOptions struct
|
||||||
func NewStepOptions(opts ...StepOption) StepOptions {
|
func NewStepOptions(opts ...StepOption) StepOptions {
|
||||||
options := StepOptions{
|
options := StepOptions{
|
||||||
Context: context.Background(),
|
Context: context.Background(),
|
||||||
@@ -211,18 +225,21 @@ func NewStepOptions(opts ...StepOption) StepOptions {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StepID sets the step id for dag
|
||||||
func StepID(id string) StepOption {
|
func StepID(id string) StepOption {
|
||||||
return func(o *StepOptions) {
|
return func(o *StepOptions) {
|
||||||
o.ID = id
|
o.ID = id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StepRequires specifies required steps
|
||||||
func StepRequires(steps ...string) StepOption {
|
func StepRequires(steps ...string) StepOption {
|
||||||
return func(o *StepOptions) {
|
return func(o *StepOptions) {
|
||||||
o.Requires = steps
|
o.Requires = steps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StepFallback set the step to run on error
|
||||||
func StepFallback(step string) StepOption {
|
func StepFallback(step string) StepOption {
|
||||||
return func(o *StepOptions) {
|
return func(o *StepOptions) {
|
||||||
o.Fallback = step
|
o.Fallback = step
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build ignore
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package micro
|
package micro
|
||||||
@@ -6,7 +7,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Function is a one time executing Service
|
// Function is a one time executing Service
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build ignore
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package micro
|
package micro
|
||||||
@@ -8,7 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/register"
|
"go.unistack.org/micro/v3/register"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFunction(t *testing.T) {
|
func TestFunction(t *testing.T) {
|
||||||
|
11
go.mod
11
go.mod
@@ -1,14 +1,13 @@
|
|||||||
module github.com/unistack-org/micro/v3
|
module go.unistack.org/micro/v3
|
||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ef-ds/deque v1.0.4
|
github.com/ef-ds/deque v1.0.4
|
||||||
github.com/golang-jwt/jwt/v4 v4.0.0
|
github.com/golang-jwt/jwt/v4 v4.2.0
|
||||||
github.com/imdario/mergo v0.3.12
|
github.com/imdario/mergo v0.3.12
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/silas/dag v0.0.0-20210121180416-41cf55125c34
|
github.com/silas/dag v0.0.0-20211117232152-9d50aa809f35
|
||||||
github.com/stretchr/testify v1.7.0
|
go.unistack.org/micro-proto/v3 v3.2.0
|
||||||
github.com/unistack-org/micro-proto v0.0.9
|
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed
|
|
||||||
)
|
)
|
||||||
|
148
go.sum
148
go.sum
@@ -1,40 +1,156 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
github.com/ef-ds/deque v1.0.4 h1:iFAZNmveMT9WERAkqLJ+oaABF9AcVQ5AjXem/hroniI=
|
github.com/ef-ds/deque v1.0.4 h1:iFAZNmveMT9WERAkqLJ+oaABF9AcVQ5AjXem/hroniI=
|
||||||
github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg=
|
github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg=
|
||||||
github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
|
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||||
|
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||||
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
|
github.com/google/gnostic v0.6.6/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
|
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/silas/dag v0.0.0-20210121180416-41cf55125c34 h1:vBfVmA5mZhsQa2jr1FOL9nfA37N/jnbBmi5XUfviVTI=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/silas/dag v0.0.0-20210121180416-41cf55125c34/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
|
github.com/silas/dag v0.0.0-20211117232152-9d50aa809f35 h1:4mohWoM/UGg1BvFFiqSPRl5uwJY3rVV0HQX0ETqauqQ=
|
||||||
|
github.com/silas/dag v0.0.0-20211117232152-9d50aa809f35/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I=
|
||||||
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/unistack-org/micro-proto v0.0.9 h1:KrWLS4FUX7UAWNAilQf70uad6ZPf/0EudeddCXllRVc=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/unistack-org/micro-proto v0.0.9/go.mod h1:Cckwmzd89gvS7ThxzZp9kQR/EOdksFQcsTAtDDyKwrg=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
|
go.unistack.org/micro-proto/v3 v3.2.0 h1:EuWXPYIRdDXgEiUEfoWWf/defUDtZfHpBeAl7MOHsSs=
|
||||||
|
go.unistack.org/micro-proto/v3 v3.2.0/go.mod h1:ZltVWNECD5yK+40+OCONzGw4OtmSdTpVi8/KFgo9dqM=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7YT6Kt14L/D73G1fuwo=
|
||||||
|
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
|
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
|
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
|
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||||
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
|
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
@@ -12,11 +12,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type defaultLogger struct {
|
type defaultLogger struct {
|
||||||
enc *json.Encoder
|
|
||||||
opts Options
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
|
enc *json.Encoder
|
||||||
logFunc LogFunc
|
logFunc LogFunc
|
||||||
logfFunc LogfFunc
|
logfFunc LogfFunc
|
||||||
|
opts Options
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init(opts...) should only overwrite provided options
|
// Init(opts...) should only overwrite provided options
|
||||||
@@ -81,7 +81,9 @@ func (l *defaultLogger) Fields(fields ...interface{}) Logger {
|
|||||||
} else if len(fields)%2 != 0 {
|
} else if len(fields)%2 != 0 {
|
||||||
fields = fields[:len(fields)-1]
|
fields = fields[:len(fields)-1]
|
||||||
}
|
}
|
||||||
nl.opts.Fields = append(l.opts.Fields, fields...)
|
nl.logFunc = l.logFunc
|
||||||
|
nl.logfFunc = l.logfFunc
|
||||||
|
nl.opts.Fields = append(nl.opts.Fields, fields...)
|
||||||
return nl
|
return nl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package logger provides a log interface
|
// Package logger provides a log interface
|
||||||
package logger
|
package logger // import "go.unistack.org/micro/v3/logger"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@@ -7,6 +7,37 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestContext(t *testing.T) {
|
||||||
|
ctx := context.TODO()
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
l := NewLogger(WithLevel(TraceLevel), WithOutput(buf))
|
||||||
|
if err := l.Init(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nl, ok := FromContext(NewContext(ctx, l.Fields("key", "val")))
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("context without logger")
|
||||||
|
}
|
||||||
|
nl.Info(ctx, "message")
|
||||||
|
if !bytes.Contains(buf.Bytes(), []byte(`"key":"val"`)) {
|
||||||
|
t.Fatalf("logger fields not works, buf contains: %s", buf.Bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFields(t *testing.T) {
|
||||||
|
ctx := context.TODO()
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
l := NewLogger(WithLevel(TraceLevel), WithOutput(buf))
|
||||||
|
if err := l.Init(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
l.Fields("key", "val").Info(ctx, "message")
|
||||||
|
if !bytes.Contains(buf.Bytes(), []byte(`"key":"val"`)) {
|
||||||
|
t.Fatalf("logger fields not works, buf contains: %s", buf.Bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestClone(t *testing.T) {
|
func TestClone(t *testing.T) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
|
@@ -19,12 +19,12 @@ type Options struct {
|
|||||||
Fields []interface{}
|
Fields []interface{}
|
||||||
// Name holds the logger name
|
// Name holds the logger name
|
||||||
Name string
|
Name string
|
||||||
// CallerSkipCount number of frmaes to skip
|
|
||||||
CallerSkipCount int
|
|
||||||
// The logging level the logger should log
|
|
||||||
Level Level
|
|
||||||
// Wrappers logger wrapper that called before actual Log/Logf function
|
// Wrappers logger wrapper that called before actual Log/Logf function
|
||||||
Wrappers []Wrapper
|
Wrappers []Wrapper
|
||||||
|
// The logging level the logger should log
|
||||||
|
Level Level
|
||||||
|
// CallerSkipCount number of frmaes to skip
|
||||||
|
CallerSkipCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOptions creates new options struct
|
// NewOptions creates new options struct
|
||||||
|
@@ -10,6 +10,7 @@ type stdLogger struct {
|
|||||||
level Level
|
level Level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewStdLogger returns new *log.Logger baked by logger.Logger implementation
|
||||||
func NewStdLogger(l Logger, level Level) *log.Logger {
|
func NewStdLogger(l Logger, level Level) *log.Logger {
|
||||||
return log.New(&stdLogger{l: l, level: level}, "" /* prefix */, 0 /* flags */)
|
return log.New(&stdLogger{l: l, level: level}, "" /* prefix */, 0 /* flags */)
|
||||||
}
|
}
|
||||||
@@ -20,6 +21,7 @@ func (sl *stdLogger) Write(p []byte) (int, error) {
|
|||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RedirectStdLogger replace *log.Logger with logger.Logger implementation
|
||||||
func RedirectStdLogger(l Logger, level Level) func() {
|
func RedirectStdLogger(l Logger, level Level) func() {
|
||||||
flags := log.Flags()
|
flags := log.Flags()
|
||||||
prefix := log.Prefix()
|
prefix := log.Prefix()
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
package logger
|
package logger // import "go.unistack.org/micro/v3/logger/wrapper"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
rutil "github.com/unistack-org/micro/v3/util/reflect"
|
rutil "go.unistack.org/micro/v3/util/reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LogFunc function used for Log method
|
// LogFunc function used for Log method
|
||||||
@@ -20,104 +20,104 @@ type Wrapper interface {
|
|||||||
Logf(LogfFunc) LogfFunc
|
Logf(LogfFunc) LogfFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Logger = &OmitLogger{}
|
var _ Logger = &omitLogger{}
|
||||||
|
|
||||||
type OmitLogger struct {
|
type omitLogger struct {
|
||||||
l Logger
|
l Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOmitLogger(l Logger) Logger {
|
func NewOmitLogger(l Logger) Logger {
|
||||||
return &OmitLogger{l: l}
|
return &omitLogger{l: l}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Init(opts ...Option) error {
|
func (w *omitLogger) Init(opts ...Option) error {
|
||||||
return w.l.Init(append(opts, WrapLogger(NewOmitWrapper()))...)
|
return w.l.Init(append(opts, WrapLogger(NewOmitWrapper()))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) V(level Level) bool {
|
func (w *omitLogger) V(level Level) bool {
|
||||||
return w.l.V(level)
|
return w.l.V(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Level(level Level) {
|
func (w *omitLogger) Level(level Level) {
|
||||||
w.l.Level(level)
|
w.l.Level(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Clone(opts ...Option) Logger {
|
func (w *omitLogger) Clone(opts ...Option) Logger {
|
||||||
return w.l.Clone(opts...)
|
return w.l.Clone(opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Options() Options {
|
func (w *omitLogger) Options() Options {
|
||||||
return w.l.Options()
|
return w.l.Options()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Fields(fields ...interface{}) Logger {
|
func (w *omitLogger) Fields(fields ...interface{}) Logger {
|
||||||
return w.l.Fields(fields...)
|
return w.l.Fields(fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Info(ctx context.Context, args ...interface{}) {
|
func (w *omitLogger) Info(ctx context.Context, args ...interface{}) {
|
||||||
w.l.Info(ctx, args...)
|
w.l.Info(ctx, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Trace(ctx context.Context, args ...interface{}) {
|
func (w *omitLogger) Trace(ctx context.Context, args ...interface{}) {
|
||||||
w.l.Trace(ctx, args...)
|
w.l.Trace(ctx, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Debug(ctx context.Context, args ...interface{}) {
|
func (w *omitLogger) Debug(ctx context.Context, args ...interface{}) {
|
||||||
w.l.Debug(ctx, args...)
|
w.l.Debug(ctx, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Warn(ctx context.Context, args ...interface{}) {
|
func (w *omitLogger) Warn(ctx context.Context, args ...interface{}) {
|
||||||
w.l.Warn(ctx, args...)
|
w.l.Warn(ctx, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Error(ctx context.Context, args ...interface{}) {
|
func (w *omitLogger) Error(ctx context.Context, args ...interface{}) {
|
||||||
w.l.Error(ctx, args...)
|
w.l.Error(ctx, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Fatal(ctx context.Context, args ...interface{}) {
|
func (w *omitLogger) Fatal(ctx context.Context, args ...interface{}) {
|
||||||
w.l.Fatal(ctx, args...)
|
w.l.Fatal(ctx, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Infof(ctx context.Context, msg string, args ...interface{}) {
|
func (w *omitLogger) Infof(ctx context.Context, msg string, args ...interface{}) {
|
||||||
w.l.Infof(ctx, msg, args...)
|
w.l.Infof(ctx, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Tracef(ctx context.Context, msg string, args ...interface{}) {
|
func (w *omitLogger) Tracef(ctx context.Context, msg string, args ...interface{}) {
|
||||||
w.l.Tracef(ctx, msg, args...)
|
w.l.Tracef(ctx, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Debugf(ctx context.Context, msg string, args ...interface{}) {
|
func (w *omitLogger) Debugf(ctx context.Context, msg string, args ...interface{}) {
|
||||||
w.l.Debugf(ctx, msg, args...)
|
w.l.Debugf(ctx, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Warnf(ctx context.Context, msg string, args ...interface{}) {
|
func (w *omitLogger) Warnf(ctx context.Context, msg string, args ...interface{}) {
|
||||||
w.l.Warnf(ctx, msg, args...)
|
w.l.Warnf(ctx, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Errorf(ctx context.Context, msg string, args ...interface{}) {
|
func (w *omitLogger) Errorf(ctx context.Context, msg string, args ...interface{}) {
|
||||||
w.l.Errorf(ctx, msg, args...)
|
w.l.Errorf(ctx, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Fatalf(ctx context.Context, msg string, args ...interface{}) {
|
func (w *omitLogger) Fatalf(ctx context.Context, msg string, args ...interface{}) {
|
||||||
w.l.Fatalf(ctx, msg, args...)
|
w.l.Fatalf(ctx, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Log(ctx context.Context, level Level, args ...interface{}) {
|
func (w *omitLogger) Log(ctx context.Context, level Level, args ...interface{}) {
|
||||||
w.l.Log(ctx, level, args...)
|
w.l.Log(ctx, level, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) Logf(ctx context.Context, level Level, msg string, args ...interface{}) {
|
func (w *omitLogger) Logf(ctx context.Context, level Level, msg string, args ...interface{}) {
|
||||||
w.l.Logf(ctx, level, msg, args...)
|
w.l.Logf(ctx, level, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitLogger) String() string {
|
func (w *omitLogger) String() string {
|
||||||
return w.l.String()
|
return w.l.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type OmitWrapper struct{}
|
type omitWrapper struct{}
|
||||||
|
|
||||||
func NewOmitWrapper() Wrapper {
|
func NewOmitWrapper() Wrapper {
|
||||||
return &OmitWrapper{}
|
return &omitWrapper{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArgs(args []interface{}) []interface{} {
|
func getArgs(args []interface{}) []interface{} {
|
||||||
@@ -125,35 +125,41 @@ func getArgs(args []interface{}) []interface{} {
|
|||||||
var err error
|
var err error
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
val := reflect.ValueOf(arg)
|
val := reflect.ValueOf(arg)
|
||||||
switch val.Kind() {
|
if val.Kind() == reflect.Ptr {
|
||||||
case reflect.Ptr:
|
|
||||||
val = val.Elem()
|
val = val.Elem()
|
||||||
}
|
}
|
||||||
narg := arg
|
narg := arg
|
||||||
if val.Kind() == reflect.Struct {
|
if val.Kind() != reflect.Struct {
|
||||||
if narg, err = rutil.Zero(arg); err == nil {
|
nargs = append(nargs, narg)
|
||||||
rutil.CopyDefaults(narg, arg)
|
continue
|
||||||
if flds, ferr := rutil.StructFields(narg); ferr == nil {
|
}
|
||||||
for _, fld := range flds {
|
|
||||||
if tv, ok := fld.Field.Tag.Lookup("logger"); ok && tv == "omit" {
|
if narg, err = rutil.Zero(arg); err != nil {
|
||||||
fld.Value.Set(reflect.Zero(fld.Value.Type()))
|
nargs = append(nargs, narg)
|
||||||
}
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rutil.CopyDefaults(narg, arg)
|
||||||
|
if flds, ferr := rutil.StructFields(narg); ferr == nil {
|
||||||
|
for _, fld := range flds {
|
||||||
|
if tv, ok := fld.Field.Tag.Lookup("logger"); ok && tv == "omit" {
|
||||||
|
fld.Value.Set(reflect.Zero(fld.Value.Type()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nargs = append(nargs, narg)
|
nargs = append(nargs, narg)
|
||||||
}
|
}
|
||||||
return nargs
|
return nargs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitWrapper) Log(fn LogFunc) LogFunc {
|
func (w *omitWrapper) Log(fn LogFunc) LogFunc {
|
||||||
return func(ctx context.Context, level Level, args ...interface{}) {
|
return func(ctx context.Context, level Level, args ...interface{}) {
|
||||||
fn(ctx, level, getArgs(args)...)
|
fn(ctx, level, getArgs(args)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *OmitWrapper) Logf(fn LogfFunc) LogfFunc {
|
func (w *omitWrapper) Logf(fn LogfFunc) LogfFunc {
|
||||||
return func(ctx context.Context, level Level, msg string, args ...interface{}) {
|
return func(ctx context.Context, level Level, msg string, args ...interface{}) {
|
||||||
fn(ctx, level, msg, getArgs(args)...)
|
fn(ctx, level, msg, getArgs(args)...)
|
||||||
}
|
}
|
||||||
|
@@ -5,9 +5,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package metadata is a way of defining message headers
|
// Package metadata is a way of defining message headers
|
||||||
package metadata
|
package metadata // import "go.unistack.org/micro/v3/metadata"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
@@ -107,13 +107,16 @@ func New(size int) Metadata {
|
|||||||
|
|
||||||
// Merge merges metadata to existing metadata, overwriting if specified
|
// Merge merges metadata to existing metadata, overwriting if specified
|
||||||
func Merge(omd Metadata, mmd Metadata, overwrite bool) Metadata {
|
func Merge(omd Metadata, mmd Metadata, overwrite bool) Metadata {
|
||||||
|
var ok bool
|
||||||
nmd := Copy(omd)
|
nmd := Copy(omd)
|
||||||
for key, val := range mmd {
|
for key, val := range mmd {
|
||||||
if _, ok := nmd[key]; ok && !overwrite {
|
_, ok = nmd[key]
|
||||||
// skip
|
switch {
|
||||||
} else if val != "" {
|
case ok && !overwrite:
|
||||||
|
continue
|
||||||
|
case val != "":
|
||||||
nmd.Set(key, val)
|
nmd.Set(key, val)
|
||||||
} else {
|
case ok && val == "":
|
||||||
nmd.Del(key)
|
nmd.Del(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,12 @@
|
|||||||
package meter
|
package meter
|
||||||
|
|
||||||
//go:generate sh -c "protoc -I./handler -I../ -I$(go list -f '{{ .Dir }}' -m github.com/unistack-org/micro-proto) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./handler handler/handler.proto"
|
//go:generate sh -c "protoc -I./handler -I../ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./handler handler/handler.proto"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "github.com/unistack-org/micro-proto/api"
|
|
||||||
_ "github.com/unistack-org/micro-proto/openapiv2"
|
// import required packages
|
||||||
|
_ "go.unistack.org/micro-proto/v3/api"
|
||||||
|
|
||||||
|
// import required packages
|
||||||
|
_ "go.unistack.org/micro-proto/v3/openapiv3"
|
||||||
)
|
)
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
package handler
|
package handler // import "go.unistack.org/micro/v3/meter/handler"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/errors"
|
"go.unistack.org/micro/v3/errors"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
)
|
)
|
||||||
|
|
||||||
// guard to fail early
|
// guard to fail early
|
||||||
|
@@ -1,24 +1,20 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
package micro.meter.handler;
|
package micro.meter.handler;
|
||||||
option go_package = "github.com/unistack-org/micro/v3/meter/handler;handler";
|
option go_package = "go.unistack.org/micro/v3/meter/handler;handler";
|
||||||
|
|
||||||
import "api/annotations.proto";
|
import "api/annotations.proto";
|
||||||
import "openapiv2/annotations.proto";
|
import "openapiv3/annotations.proto";
|
||||||
import "codec/frame.proto";
|
import "codec/frame.proto";
|
||||||
|
|
||||||
service Meter {
|
service Meter {
|
||||||
rpc Metrics(micro.codec.Frame) returns (micro.codec.Frame) {
|
rpc Metrics(micro.codec.Frame) returns (micro.codec.Frame) {
|
||||||
option (micro.openapiv2.openapiv2_operation) = {
|
option (micro.openapiv3.openapiv3_operation) = {
|
||||||
operation_id: "Metrics";
|
operation_id: "Metrics";
|
||||||
responses: {
|
responses: {
|
||||||
response_code: {
|
default: {
|
||||||
name: "default";
|
reference: {
|
||||||
value: {
|
_ref: "micro.codec.Frame";
|
||||||
json_reference: {
|
|
||||||
description: "Error response";
|
|
||||||
_ref: "micro.codec.Frame";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
|
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
|
||||||
// protoc-gen-go-micro version: v3.4.2
|
// protoc-gen-go-micro version: v3.5.3
|
||||||
// source: handler.proto
|
// source: handler.proto
|
||||||
|
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
api "github.com/unistack-org/micro/v3/api"
|
api "go.unistack.org/micro/v3/api"
|
||||||
codec "github.com/unistack-org/micro/v3/codec"
|
codec "go.unistack.org/micro/v3/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
|
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
|
||||||
// protoc-gen-go-micro version: v3.4.2
|
// protoc-gen-go-micro version: v3.5.3
|
||||||
// source: handler.proto
|
// source: handler.proto
|
||||||
|
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
api "github.com/unistack-org/micro/v3/api"
|
api "go.unistack.org/micro/v3/api"
|
||||||
codec "github.com/unistack-org/micro/v3/codec"
|
codec "go.unistack.org/micro/v3/codec"
|
||||||
server "github.com/unistack-org/micro/v3/server"
|
server "go.unistack.org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
type meterServer struct {
|
type meterServer struct {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package meter is for instrumentation
|
// Package meter is for instrumentation
|
||||||
package meter
|
package meter // import "go.unistack.org/micro/v3/meter"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@@ -28,17 +28,31 @@ var (
|
|||||||
|
|
||||||
// Meter is an interface for collecting and instrumenting metrics
|
// Meter is an interface for collecting and instrumenting metrics
|
||||||
type Meter interface {
|
type Meter interface {
|
||||||
|
// Name returns meter name
|
||||||
Name() string
|
Name() string
|
||||||
|
// Init initialize meter
|
||||||
Init(opts ...Option) error
|
Init(opts ...Option) error
|
||||||
|
// Clone create meter copy with new options
|
||||||
|
Clone(opts ...Option) Meter
|
||||||
|
// Counter get or create counter
|
||||||
Counter(name string, labels ...string) Counter
|
Counter(name string, labels ...string) Counter
|
||||||
|
// FloatCounter get or create float counter
|
||||||
FloatCounter(name string, labels ...string) FloatCounter
|
FloatCounter(name string, labels ...string) FloatCounter
|
||||||
|
// Gauge get or create gauge
|
||||||
Gauge(name string, fn func() float64, labels ...string) Gauge
|
Gauge(name string, fn func() float64, labels ...string) Gauge
|
||||||
|
// Set create new meter metrics set
|
||||||
Set(opts ...Option) Meter
|
Set(opts ...Option) Meter
|
||||||
|
// Histogram get or create histogram
|
||||||
Histogram(name string, labels ...string) Histogram
|
Histogram(name string, labels ...string) Histogram
|
||||||
|
// Summary get or create summary
|
||||||
Summary(name string, labels ...string) Summary
|
Summary(name string, labels ...string) Summary
|
||||||
|
// SummaryExt get or create summary with spcified quantiles and window time
|
||||||
SummaryExt(name string, window time.Duration, quantiles []float64, labels ...string) Summary
|
SummaryExt(name string, window time.Duration, quantiles []float64, labels ...string) Summary
|
||||||
|
// Write writes metrics to io.Writer
|
||||||
Write(w io.Writer, opts ...Option) error
|
Write(w io.Writer, opts ...Option) error
|
||||||
|
// Options returns meter options
|
||||||
Options() Options
|
Options() Options
|
||||||
|
// String return meter type
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ func TestBuildLabels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data := []testData{
|
data := []testData{
|
||||||
testData{
|
{
|
||||||
src: []string{"zerolabel", "value3", "firstlabel", "value2"},
|
src: []string{"zerolabel", "value3", "firstlabel", "value2"},
|
||||||
dst: []string{"firstlabel", "value2", "zerolabel", "value3"},
|
dst: []string{"firstlabel", "value2", "zerolabel", "value3"},
|
||||||
},
|
},
|
||||||
@@ -48,15 +48,15 @@ func TestBuildLabels(t *testing.T) {
|
|||||||
|
|
||||||
func TestBuildName(t *testing.T) {
|
func TestBuildName(t *testing.T) {
|
||||||
data := map[string][]string{
|
data := map[string][]string{
|
||||||
`my_metric{firstlabel="value2",zerolabel="value3"}`: []string{
|
`my_metric{firstlabel="value2",zerolabel="value3"}`: {
|
||||||
"my_metric",
|
"my_metric",
|
||||||
"zerolabel", "value3", "firstlabel", "value2",
|
"zerolabel", "value3", "firstlabel", "value2",
|
||||||
},
|
},
|
||||||
`my_metric{broker="broker2",register="mdns",server="tcp"}`: []string{
|
`my_metric{broker="broker2",register="mdns",server="tcp"}`: {
|
||||||
"my_metric",
|
"my_metric",
|
||||||
"broker", "broker1", "broker", "broker2", "server", "http", "server", "tcp", "register", "mdns",
|
"broker", "broker1", "broker", "broker2", "server", "http", "server", "tcp", "register", "mdns",
|
||||||
},
|
},
|
||||||
`my_metric{aaa="aaa"}`: []string{
|
`my_metric{aaa="aaa"}`: {
|
||||||
"my_metric",
|
"my_metric",
|
||||||
"aaa", "aaa",
|
"aaa", "aaa",
|
||||||
},
|
},
|
||||||
|
@@ -15,6 +15,15 @@ func NewMeter(opts ...Option) Meter {
|
|||||||
return &noopMeter{opts: NewOptions(opts...)}
|
return &noopMeter{opts: NewOptions(opts...)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clone return old meter with new options
|
||||||
|
func (r *noopMeter) Clone(opts ...Option) Meter {
|
||||||
|
options := r.opts
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
return &noopMeter{opts: options}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *noopMeter) Name() string {
|
func (r *noopMeter) Name() string {
|
||||||
return r.opts.Name
|
return r.opts.Name
|
||||||
}
|
}
|
||||||
|
@@ -3,13 +3,13 @@ package meter
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Option powers the configuration for metrics implementations:
|
// Option powers the configuration for metrics implementations:
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
|
|
||||||
// Options for metrics implementations:
|
// Options for metrics implementations
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// Logger used for logging
|
// Logger used for logging
|
||||||
Logger logger.Logger
|
Logger logger.Logger
|
||||||
@@ -51,6 +51,20 @@ func NewOptions(opt ...Option) Options {
|
|||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LabelPrefix sets the labels prefix
|
||||||
|
func LabelPrefix(pref string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.LabelPrefix = pref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MetricPrefix sets the metric prefix
|
||||||
|
func MetricPrefix(pref string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.MetricPrefix = pref
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Context sets the metrics context
|
// Context sets the metrics context
|
||||||
func Context(ctx context.Context) Option {
|
func Context(ctx context.Context) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
@@ -88,6 +102,7 @@ func Logger(l logger.Logger) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Labels sets the meter labels
|
||||||
func Labels(ls ...string) Option {
|
func Labels(ls ...string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Labels = append(o.Labels, ls...)
|
o.Labels = append(o.Labels, ls...)
|
||||||
|
@@ -1,35 +1,48 @@
|
|||||||
package wrapper
|
package wrapper // import "go.unistack.org/micro/v3/meter/wrapper"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ClientRequestDurationSeconds = "client_request_duration_seconds"
|
// ClientRequestDurationSeconds specifies meter metric name
|
||||||
|
ClientRequestDurationSeconds = "client_request_duration_seconds"
|
||||||
|
// ClientRequestLatencyMicroseconds specifies meter metric name
|
||||||
ClientRequestLatencyMicroseconds = "client_request_latency_microseconds"
|
ClientRequestLatencyMicroseconds = "client_request_latency_microseconds"
|
||||||
ClientRequestTotal = "client_request_total"
|
// ClientRequestTotal specifies meter metric name
|
||||||
ClientRequestInflight = "client_request_inflight"
|
ClientRequestTotal = "client_request_total"
|
||||||
|
// ClientRequestInflight specifies meter metric name
|
||||||
ServerRequestDurationSeconds = "server_request_duration_seconds"
|
ClientRequestInflight = "client_request_inflight"
|
||||||
|
// ServerRequestDurationSeconds specifies meter metric name
|
||||||
|
ServerRequestDurationSeconds = "server_request_duration_seconds"
|
||||||
|
// ServerRequestLatencyMicroseconds specifies meter metric name
|
||||||
ServerRequestLatencyMicroseconds = "server_request_latency_microseconds"
|
ServerRequestLatencyMicroseconds = "server_request_latency_microseconds"
|
||||||
ServerRequestTotal = "server_request_total"
|
// ServerRequestTotal specifies meter metric name
|
||||||
ServerRequestInflight = "server_request_inflight"
|
ServerRequestTotal = "server_request_total"
|
||||||
|
// ServerRequestInflight specifies meter metric name
|
||||||
PublishMessageDurationSeconds = "publish_message_duration_seconds"
|
ServerRequestInflight = "server_request_inflight"
|
||||||
|
// PublishMessageDurationSeconds specifies meter metric name
|
||||||
|
PublishMessageDurationSeconds = "publish_message_duration_seconds"
|
||||||
|
// PublishMessageLatencyMicroseconds specifies meter metric name
|
||||||
PublishMessageLatencyMicroseconds = "publish_message_latency_microseconds"
|
PublishMessageLatencyMicroseconds = "publish_message_latency_microseconds"
|
||||||
PublishMessageTotal = "publish_message_total"
|
// PublishMessageTotal specifies meter metric name
|
||||||
PublishMessageInflight = "publish_message_inflight"
|
PublishMessageTotal = "publish_message_total"
|
||||||
|
// PublishMessageInflight specifies meter metric name
|
||||||
SubscribeMessageDurationSeconds = "subscribe_message_duration_seconds"
|
PublishMessageInflight = "publish_message_inflight"
|
||||||
|
// SubscribeMessageDurationSeconds specifies meter metric name
|
||||||
|
SubscribeMessageDurationSeconds = "subscribe_message_duration_seconds"
|
||||||
|
// SubscribeMessageLatencyMicroseconds specifies meter metric name
|
||||||
SubscribeMessageLatencyMicroseconds = "subscribe_message_latency_microseconds"
|
SubscribeMessageLatencyMicroseconds = "subscribe_message_latency_microseconds"
|
||||||
SubscribeMessageTotal = "subscribe_message_total"
|
// SubscribeMessageTotal specifies meter metric name
|
||||||
SubscribeMessageInflight = "subscribe_message_inflight"
|
SubscribeMessageTotal = "subscribe_message_total"
|
||||||
|
// SubscribeMessageInflight specifies meter metric name
|
||||||
|
SubscribeMessageInflight = "subscribe_message_inflight"
|
||||||
|
|
||||||
labelSuccess = "success"
|
labelSuccess = "success"
|
||||||
labelFailure = "failure"
|
labelFailure = "failure"
|
||||||
@@ -40,14 +53,17 @@ var (
|
|||||||
DefaultSkipEndpoints = []string{"Meter.Metrics"}
|
DefaultSkipEndpoints = []string{"Meter.Metrics"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Options struct
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Meter meter.Meter
|
Meter meter.Meter
|
||||||
lopts []meter.Option
|
lopts []meter.Option
|
||||||
SkipEndpoints []string
|
SkipEndpoints []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option func signature
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
|
|
||||||
|
// NewOptions creates new Options struct
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
options := Options{
|
options := Options{
|
||||||
Meter: meter.DefaultMeter,
|
Meter: meter.DefaultMeter,
|
||||||
@@ -60,30 +76,35 @@ func NewOptions(opts ...Option) Options {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceName passes service name to meter label
|
||||||
func ServiceName(name string) Option {
|
func ServiceName(name string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.lopts = append(o.lopts, meter.Labels("name", name))
|
o.lopts = append(o.lopts, meter.Labels("name", name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceVersion passes service version to meter label
|
||||||
func ServiceVersion(version string) Option {
|
func ServiceVersion(version string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.lopts = append(o.lopts, meter.Labels("version", version))
|
o.lopts = append(o.lopts, meter.Labels("version", version))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceID passes service id to meter label
|
||||||
func ServiceID(id string) Option {
|
func ServiceID(id string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.lopts = append(o.lopts, meter.Labels("id", id))
|
o.lopts = append(o.lopts, meter.Labels("id", id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Meter passes meter
|
||||||
func Meter(m meter.Meter) Option {
|
func Meter(m meter.Meter) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Meter = m
|
o.Meter = m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SkipEndpoint add endpoint to skip
|
||||||
func SkipEndoints(eps ...string) Option {
|
func SkipEndoints(eps ...string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.SkipEndpoints = append(o.SkipEndpoints, eps...)
|
o.SkipEndpoints = append(o.SkipEndpoints, eps...)
|
||||||
@@ -96,6 +117,7 @@ type wrapper struct {
|
|||||||
opts Options
|
opts Options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewClientWrapper create new client wrapper
|
||||||
func NewClientWrapper(opts ...Option) client.Wrapper {
|
func NewClientWrapper(opts ...Option) client.Wrapper {
|
||||||
return func(c client.Client) client.Client {
|
return func(c client.Client) client.Client {
|
||||||
handler := &wrapper{
|
handler := &wrapper{
|
||||||
@@ -106,6 +128,7 @@ func NewClientWrapper(opts ...Option) client.Wrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewCallWrapper create new call wrapper
|
||||||
func NewCallWrapper(opts ...Option) client.CallWrapper {
|
func NewCallWrapper(opts ...Option) client.CallWrapper {
|
||||||
return func(fn client.CallFunc) client.CallFunc {
|
return func(fn client.CallFunc) client.CallFunc {
|
||||||
handler := &wrapper{
|
handler := &wrapper{
|
||||||
@@ -231,6 +254,7 @@ func (w *wrapper) Publish(ctx context.Context, p client.Message, opts ...client.
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHandlerWrapper create new server handler wrapper
|
||||||
func NewHandlerWrapper(opts ...Option) server.HandlerWrapper {
|
func NewHandlerWrapper(opts ...Option) server.HandlerWrapper {
|
||||||
handler := &wrapper{
|
handler := &wrapper{
|
||||||
opts: NewOptions(opts...),
|
opts: NewOptions(opts...),
|
||||||
@@ -240,7 +264,7 @@ func NewHandlerWrapper(opts ...Option) server.HandlerWrapper {
|
|||||||
|
|
||||||
func (w *wrapper) HandlerFunc(fn server.HandlerFunc) server.HandlerFunc {
|
func (w *wrapper) HandlerFunc(fn server.HandlerFunc) server.HandlerFunc {
|
||||||
return func(ctx context.Context, req server.Request, rsp interface{}) error {
|
return func(ctx context.Context, req server.Request, rsp interface{}) error {
|
||||||
endpoint := req.Endpoint()
|
endpoint := req.Service() + "." + req.Endpoint()
|
||||||
for _, ep := range w.opts.SkipEndpoints {
|
for _, ep := range w.opts.SkipEndpoints {
|
||||||
if ep == endpoint {
|
if ep == endpoint {
|
||||||
return fn(ctx, req, rsp)
|
return fn(ctx, req, rsp)
|
||||||
@@ -270,6 +294,7 @@ func (w *wrapper) HandlerFunc(fn server.HandlerFunc) server.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewSubscribeWrapper create server subscribe wrapper
|
||||||
func NewSubscriberWrapper(opts ...Option) server.SubscriberWrapper {
|
func NewSubscriberWrapper(opts ...Option) server.SubscriberWrapper {
|
||||||
handler := &wrapper{
|
handler := &wrapper{
|
||||||
opts: NewOptions(opts...),
|
opts: NewOptions(opts...),
|
||||||
|
@@ -1,35 +0,0 @@
|
|||||||
// +build ignore
|
|
||||||
|
|
||||||
// Package model is an interface for data modelling
|
|
||||||
package model
|
|
||||||
|
|
||||||
// Model provides an interface for data modelling
|
|
||||||
type Model interface {
|
|
||||||
// Initialise options
|
|
||||||
Init(...Option) error
|
|
||||||
// NewEntity creates a new entity to store or access
|
|
||||||
NewEntity(name string, value interface{}) Entity
|
|
||||||
// Create a value
|
|
||||||
Create(Entity) error
|
|
||||||
// Read values
|
|
||||||
Read(...ReadOption) ([]Entity, error)
|
|
||||||
// Update the value
|
|
||||||
Update(Entity) error
|
|
||||||
// Delete an entity
|
|
||||||
Delete(...DeleteOption) error
|
|
||||||
// Implementation of the model
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Entity interface {
|
|
||||||
// Unique id of the entity
|
|
||||||
Id() string
|
|
||||||
// Name of the entity
|
|
||||||
Name() string
|
|
||||||
// The value associated with the entity
|
|
||||||
Value() interface{}
|
|
||||||
// Attributes of the entity
|
|
||||||
Attributes() map[string]interface{}
|
|
||||||
// Read a value as a concrete type
|
|
||||||
Read(v interface{}) error
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
// +build ignore
|
|
||||||
|
|
||||||
// Package model is an interface for data modelling
|
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
|
||||||
"github.com/unistack-org/micro/v3/store"
|
|
||||||
"github.com/unistack-org/micro/v3/sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Options struct {
|
|
||||||
// Database to write to
|
|
||||||
Database string
|
|
||||||
// for serialising
|
|
||||||
Codec codec.Codec
|
|
||||||
// for locking
|
|
||||||
Sync sync.Sync
|
|
||||||
// for storage
|
|
||||||
Store store.Store
|
|
||||||
// for logger
|
|
||||||
Logger logger.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
type Option func(o *Options)
|
|
||||||
|
|
||||||
// Logger sets the logger
|
|
||||||
func Logger(l logger.Logger) Option {
|
|
||||||
return func(o *Options) {
|
|
||||||
o.Logger = l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReadOptions struct{}
|
|
||||||
|
|
||||||
type ReadOption func(o *ReadOptions)
|
|
||||||
|
|
||||||
type DeleteOptions struct{}
|
|
||||||
|
|
||||||
type DeleteOption func(o *DeleteOptions)
|
|
@@ -1,9 +1,9 @@
|
|||||||
// Package network is for creating internetworks
|
// Package network is for creating internetworks
|
||||||
package network
|
package network // import "go.unistack.org/micro/v3/network"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error is network node errors
|
// Error is network node errors
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/network/tunnel"
|
"go.unistack.org/micro/v3/network/tunnel"
|
||||||
"github.com/unistack-org/micro/v3/proxy"
|
"go.unistack.org/micro/v3/proxy"
|
||||||
"github.com/unistack-org/micro/v3/router"
|
"go.unistack.org/micro/v3/router"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
"github.com/unistack-org/micro/v3/util/id"
|
"go.unistack.org/micro/v3/util/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Option func
|
// Option func
|
||||||
@@ -27,8 +27,8 @@ type Options struct {
|
|||||||
Tracer tracer.Tracer
|
Tracer tracer.Tracer
|
||||||
// Tunnel used for transfer data
|
// Tunnel used for transfer data
|
||||||
Tunnel tunnel.Tunnel
|
Tunnel tunnel.Tunnel
|
||||||
// Id of the node
|
// ID of the node
|
||||||
Id string
|
ID string
|
||||||
// Name of the network
|
// Name of the network
|
||||||
Name string
|
Name string
|
||||||
// Address to bind to
|
// Address to bind to
|
||||||
@@ -39,10 +39,10 @@ type Options struct {
|
|||||||
Nodes []string
|
Nodes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Id sets the id of the network node
|
// ID sets the id of the network node
|
||||||
func Id(id string) Option {
|
func ID(id string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Id = id
|
o.ID = id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ func Tracer(t tracer.Tracer) Option {
|
|||||||
// NewOptions returns network default options
|
// NewOptions returns network default options
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
options := Options{
|
options := Options{
|
||||||
Id: id.Must(),
|
ID: id.Must(),
|
||||||
Name: "go.micro",
|
Name: "go.micro",
|
||||||
Address: ":0",
|
Address: ":0",
|
||||||
Logger: logger.DefaultLogger,
|
Logger: logger.DefaultLogger,
|
||||||
|
@@ -8,9 +8,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
maddr "github.com/unistack-org/micro/v3/util/addr"
|
maddr "go.unistack.org/micro/v3/util/addr"
|
||||||
mnet "github.com/unistack-org/micro/v3/util/net"
|
mnet "go.unistack.org/micro/v3/util/net"
|
||||||
"github.com/unistack-org/micro/v3/util/rand"
|
"go.unistack.org/micro/v3/util/rand"
|
||||||
)
|
)
|
||||||
|
|
||||||
type memorySocket struct {
|
type memorySocket struct {
|
||||||
|
@@ -16,12 +16,14 @@ func TestMemoryTransport(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer l.Close()
|
defer l.Close()
|
||||||
|
|
||||||
|
cherr := make(chan error, 1)
|
||||||
// accept
|
// accept
|
||||||
go func() {
|
go func() {
|
||||||
if err := l.Accept(func(sock Socket) {
|
if nerr := l.Accept(func(sock Socket) {
|
||||||
for {
|
for {
|
||||||
var m Message
|
var m Message
|
||||||
if err := sock.Recv(&m); err != nil {
|
if rerr := sock.Recv(&m); rerr != nil {
|
||||||
|
cherr <- rerr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(os.Getenv("INTEGRATION_TESTS")) == 0 {
|
if len(os.Getenv("INTEGRATION_TESTS")) == 0 {
|
||||||
@@ -30,11 +32,12 @@ func TestMemoryTransport(t *testing.T) {
|
|||||||
if cerr := sock.Send(&Message{
|
if cerr := sock.Send(&Message{
|
||||||
Body: []byte(`pong`),
|
Body: []byte(`pong`),
|
||||||
}); cerr != nil {
|
}); cerr != nil {
|
||||||
|
cherr <- cerr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}); err != nil {
|
}); nerr != nil {
|
||||||
t.Fatalf("Unexpected error accepting %v", err)
|
cherr <- err
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -45,19 +48,24 @@ func TestMemoryTransport(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
// send <=> receive
|
select {
|
||||||
for i := 0; i < 3; i++ {
|
case err := <-cherr:
|
||||||
if err := c.Send(&Message{
|
t.Fatal(err)
|
||||||
Body: []byte(`ping`),
|
default:
|
||||||
}); err != nil {
|
// send <=> receive
|
||||||
return
|
for i := 0; i < 3; i++ {
|
||||||
}
|
if err := c.Send(&Message{
|
||||||
var m Message
|
Body: []byte(`ping`),
|
||||||
if err := c.Recv(&m); err != nil {
|
}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(os.Getenv("INTEGRATION_TESTS")) == 0 {
|
var m Message
|
||||||
t.Logf("Client Received %s", string(m.Body))
|
if err := c.Recv(&m); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(os.Getenv("INTEGRATION_TESTS")) == 0 {
|
||||||
|
t.Logf("Client Received %s", string(m.Body))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,10 +5,10 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/codec"
|
"go.unistack.org/micro/v3/codec"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options struct holds the transport options
|
// Options struct holds the transport options
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
// Package transport is an interface for synchronous connection based communication
|
// Package transport is an interface for synchronous connection based communication
|
||||||
package transport
|
package transport // import "go.unistack.org/micro/v3/network/transport"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
// Package broker is a tunnel broker
|
// Package broker is a tunnel broker
|
||||||
package broker
|
package broker // import "go.unistack.org/micro/v3/network/tunnel/broker"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/broker"
|
"go.unistack.org/micro/v3/broker"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
"github.com/unistack-org/micro/v3/network/transport"
|
"go.unistack.org/micro/v3/network/transport"
|
||||||
"github.com/unistack-org/micro/v3/network/tunnel"
|
"go.unistack.org/micro/v3/network/tunnel"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tunBroker struct {
|
type tunBroker struct {
|
||||||
@@ -34,9 +34,9 @@ type tunBatchSubscriber struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type tunEvent struct {
|
type tunEvent struct {
|
||||||
|
err error
|
||||||
message *broker.Message
|
message *broker.Message
|
||||||
topic string
|
topic string
|
||||||
err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// used to access tunnel from options context
|
// used to access tunnel from options context
|
||||||
@@ -82,7 +82,7 @@ func (t *tunBroker) BatchPublish(ctx context.Context, msgs []*broker.Message, op
|
|||||||
topic, _ := msg.Header.Get(metadata.HeaderTopic)
|
topic, _ := msg.Header.Get(metadata.HeaderTopic)
|
||||||
c, ok := topicMap[topic]
|
c, ok := topicMap[topic]
|
||||||
if !ok {
|
if !ok {
|
||||||
c, err := t.tunnel.Dial(ctx, topic, tunnel.DialMode(tunnel.Multicast))
|
c, err = t.tunnel.Dial(ctx, topic, tunnel.DialMode(tunnel.Multicast))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,9 @@ func (t *tunBatchSubscriber) run() {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
// handle the message
|
// handle the message
|
||||||
go t.handler(evts)
|
go func() {
|
||||||
|
_ = t.handler(evts)
|
||||||
|
}()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,13 +237,15 @@ func (t *tunSubscriber) run() {
|
|||||||
c.Close()
|
c.Close()
|
||||||
|
|
||||||
// handle the message
|
// handle the message
|
||||||
go t.handler(&tunEvent{
|
go func() {
|
||||||
topic: t.topic,
|
_ = t.handler(&tunEvent{
|
||||||
message: &broker.Message{
|
topic: t.topic,
|
||||||
Header: m.Header,
|
message: &broker.Message{
|
||||||
Body: m.Body,
|
Header: m.Header,
|
||||||
},
|
Body: m.Body,
|
||||||
})
|
},
|
||||||
|
})
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,11 +3,11 @@ package tunnel
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/network/transport"
|
"go.unistack.org/micro/v3/network/transport"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
"github.com/unistack-org/micro/v3/util/id"
|
"go.unistack.org/micro/v3/util/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
package transport
|
package transport
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/network/transport"
|
"go.unistack.org/micro/v3/network/transport"
|
||||||
"github.com/unistack-org/micro/v3/network/tunnel"
|
"go.unistack.org/micro/v3/network/tunnel"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tunListener struct {
|
type tunListener struct {
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
// Package transport provides a tunnel transport
|
// Package transport provides a tunnel transport
|
||||||
package transport
|
package transport // import "go.unistack.org/micro/v3/network/tunnel/transport"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/network/transport"
|
"go.unistack.org/micro/v3/network/transport"
|
||||||
"github.com/unistack-org/micro/v3/network/tunnel"
|
"go.unistack.org/micro/v3/network/tunnel"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tunTransport struct {
|
type tunTransport struct {
|
||||||
@@ -37,7 +37,7 @@ func (t *tunTransport) Init(opts ...transport.Option) error {
|
|||||||
// get the transport
|
// get the transport
|
||||||
tr, ok := t.options.Context.Value(transportKey{}).(transport.Transport)
|
tr, ok := t.options.Context.Value(transportKey{}).(transport.Transport)
|
||||||
if ok {
|
if ok {
|
||||||
tun.Init(tunnel.Transport(tr))
|
_ = tun.Init(tunnel.Transport(tr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the tunnel
|
// set the tunnel
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
// Package tunnel provides gre network tunnelling
|
// Package tunnel provides gre network tunnelling
|
||||||
package tunnel
|
package tunnel // import "go.unistack.org/micro/v3/network/transport/tunnel"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/network/transport"
|
"go.unistack.org/micro/v3/network/transport"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultTunnel contains default tunnel implementation
|
// DefaultTunnel contains default tunnel implementation
|
||||||
|
24
options.go
24
options.go
@@ -5,18 +5,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/auth"
|
"go.unistack.org/micro/v3/auth"
|
||||||
"github.com/unistack-org/micro/v3/broker"
|
"go.unistack.org/micro/v3/broker"
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/config"
|
"go.unistack.org/micro/v3/config"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/register"
|
"go.unistack.org/micro/v3/register"
|
||||||
"github.com/unistack-org/micro/v3/router"
|
"go.unistack.org/micro/v3/router"
|
||||||
"github.com/unistack-org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
"github.com/unistack-org/micro/v3/store"
|
"go.unistack.org/micro/v3/store"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options for micro service
|
// Options for micro service
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package http enables the http profiler
|
// Package http enables the http profiler
|
||||||
package http
|
package http // import "go.unistack.org/micro/v3/profiler/http"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"net/http/pprof"
|
"net/http/pprof"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
profile "github.com/unistack-org/micro/v3/profiler"
|
profile "go.unistack.org/micro/v3/profiler"
|
||||||
)
|
)
|
||||||
|
|
||||||
type httpProfile struct {
|
type httpProfile struct {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package pprof provides a pprof profiler which writes output to /tmp/[name].{cpu,mem}.pprof
|
// Package pprof provides a pprof profiler which writes output to /tmp/[name].{cpu,mem}.pprof
|
||||||
package pprof
|
package pprof // import "go.unistack.org/micro/v3/profiler/pprof"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
profile "github.com/unistack-org/micro/v3/profiler"
|
profile "go.unistack.org/micro/v3/profiler"
|
||||||
)
|
)
|
||||||
|
|
||||||
type profiler struct {
|
type profiler struct {
|
||||||
@@ -31,7 +31,7 @@ func (p *profiler) writeHeap(f *os.File) {
|
|||||||
select {
|
select {
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
pprof.WriteHeapProfile(f)
|
_ = pprof.WriteHeapProfile(f)
|
||||||
case <-p.exit:
|
case <-p.exit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package profiler is for profilers
|
// Package profiler is for profilers
|
||||||
package profiler
|
package profiler // import "go.unistack.org/micro/v3/profiler"
|
||||||
|
|
||||||
// Profiler interface
|
// Profiler interface
|
||||||
type Profiler interface {
|
type Profiler interface {
|
||||||
|
@@ -2,11 +2,11 @@
|
|||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/unistack-org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/router"
|
"go.unistack.org/micro/v3/router"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options for proxy
|
// Options for proxy
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
// Package proxy is a transparent proxy built on the micro/server
|
// Package proxy is a transparent proxy built on the micro/server
|
||||||
package proxy
|
package proxy // import "go.unistack.org/micro/v3/proxy"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultEndpoint holds default proxy address
|
// DefaultEndpoint holds default proxy address
|
||||||
|
@@ -6,7 +6,7 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExtractValue from reflect.Type from specified depth
|
// ExtractValue from reflect.Type from specified depth
|
||||||
|
@@ -51,6 +51,4 @@ func TestExtractEndpoint(t *testing.T) {
|
|||||||
if endpoints[0].Response != "TestResponse" {
|
if endpoints[0].Response != "TestResponse" {
|
||||||
t.Fatalf("Expected TestResponse got %s", endpoints[0].Response)
|
t.Fatalf("Expected TestResponse got %s", endpoints[0].Response)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("XXX %#+v\n", endpoints[0])
|
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/util/id"
|
"go.unistack.org/micro/v3/util/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -5,9 +5,9 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"github.com/unistack-org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"github.com/unistack-org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options holds options for register
|
// Options holds options for register
|
||||||
@@ -44,7 +44,7 @@ func NewOptions(opts ...Option) Options {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: golint
|
// nolint: golint,revive
|
||||||
// RegisterOptions holds options for register method
|
// RegisterOptions holds options for register method
|
||||||
type RegisterOptions struct {
|
type RegisterOptions struct {
|
||||||
Context context.Context
|
Context context.Context
|
||||||
@@ -197,7 +197,7 @@ func TLSConfig(t *tls.Config) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: golint
|
// nolint: golint,revive
|
||||||
// RegisterAttempts specifies register atempts count
|
// RegisterAttempts specifies register atempts count
|
||||||
func RegisterAttempts(t int) RegisterOption {
|
func RegisterAttempts(t int) RegisterOption {
|
||||||
return func(o *RegisterOptions) {
|
return func(o *RegisterOptions) {
|
||||||
@@ -205,7 +205,7 @@ func RegisterAttempts(t int) RegisterOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: golint
|
// nolint: golint,revive
|
||||||
// RegisterTTL specifies register ttl
|
// RegisterTTL specifies register ttl
|
||||||
func RegisterTTL(t time.Duration) RegisterOption {
|
func RegisterTTL(t time.Duration) RegisterOption {
|
||||||
return func(o *RegisterOptions) {
|
return func(o *RegisterOptions) {
|
||||||
@@ -213,7 +213,7 @@ func RegisterTTL(t time.Duration) RegisterOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: golint
|
// nolint: golint,revive
|
||||||
// RegisterContext sets the register context
|
// RegisterContext sets the register context
|
||||||
func RegisterContext(ctx context.Context) RegisterOption {
|
func RegisterContext(ctx context.Context) RegisterOption {
|
||||||
return func(o *RegisterOptions) {
|
return func(o *RegisterOptions) {
|
||||||
@@ -221,7 +221,7 @@ func RegisterContext(ctx context.Context) RegisterOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: golint
|
// nolint: golint,revive
|
||||||
// RegisterDomain secifies register domain
|
// RegisterDomain secifies register domain
|
||||||
func RegisterDomain(d string) RegisterOption {
|
func RegisterDomain(d string) RegisterOption {
|
||||||
return func(o *RegisterOptions) {
|
return func(o *RegisterOptions) {
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
// Package register is an interface for service discovery
|
// Package register is an interface for service discovery
|
||||||
package register
|
package register // import "go.unistack.org/micro/v3/register"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/metadata"
|
"go.unistack.org/micro/v3/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -68,8 +68,8 @@ type Endpoint struct {
|
|||||||
// Option func signature
|
// Option func signature
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
|
|
||||||
|
// nolint: golint,revive
|
||||||
// RegisterOption option is used to register service
|
// RegisterOption option is used to register service
|
||||||
// nolint: golint
|
|
||||||
type RegisterOption func(*RegisterOptions)
|
type RegisterOption func(*RegisterOptions)
|
||||||
|
|
||||||
// WatchOption option is used to watch service changes
|
// WatchOption option is used to watch service changes
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
// Package dns resolves names to dns records
|
// Package dns resolves names to dns records
|
||||||
package dns
|
package dns // import "go.unistack.org/micro/v3/resolver/dns"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/unistack-org/micro/v3/resolver"
|
"go.unistack.org/micro/v3/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resolver is a DNS network resolve
|
// Resolver is a DNS network resolve
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user