Skip to content

Commit

Permalink
Merge pull request #13 from ksysoev/add_golangci_lint
Browse files Browse the repository at this point in the history
Lint code and add linting configuration
  • Loading branch information
ksysoev authored Aug 17, 2024
2 parents b0c4460 + b3ea2b2 commit 854eb1f
Show file tree
Hide file tree
Showing 260 changed files with 16,233 additions and 16,306 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ jobs:

- name: Display Go version
run: go version

- name: Code Lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.55.2
- name: Build
run: go build -v .
- name: Test
Expand Down
67 changes: 67 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
linters-settings:
exhaustive:
default-signifies-exhaustive: true
errcheck:
check-type-assertions: true
goconst:
min-len: 2
min-occurrences: 3
gocritic:
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
govet:
check-shadowing: true
enable:
- fieldalignment
nolintlint:
require-explanation: true
require-specific: true

linters:
disable-all: true
enable:
- bodyclose
- dogsled
- dupl
- errcheck
- exportloopref
- exhaustive
- goconst
- gocritic
- gofmt
- goimports
- gomnd
- gocyclo
- gosec
- gosimple
- govet
- ineffassign
- misspell
- nolintlint
- nakedret
- prealloc
- predeclared
- revive
- staticcheck
- stylecheck
- thelper
- tparallel
- typecheck
- unconvert
- unparam
- unused
- whitespace
- wsl

issues:
exclude-rules:
- path: _test\.go$
linters:
- goconst

run:
issues-exit-code: 1
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ coverage:
cat coverage.out | grep -v "/calls.go" | grep -v "custom_subscription_calls.go" | grep -v "subscription_calls.go" > coverage.final.out
go tool cover -func=coverage.final.out
rm coverage.out coverage.final.out

lint:
golangci-lint run
95 changes: 47 additions & 48 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,42 @@ import (
"github.com/ksysoev/deriv-api/schema"
)

const (
// DefaultKeepAliveInterval is the default interval for sending ping requests to keep the connection alive.
keepAliveInterval = 25 * time.Second
defaultTimeout = 30 * time.Second
)

// DerivAPI is the main struct for the DerivAPI client.
type DerivAPI struct {
Origin *url.URL // The origin URL for the DerivAPI server
Endpoint *url.URL // The WebSocket endpoint URL for the DerivAPI server
AppID int // The app ID for the DerivAPI server
Lang string // The language code (ISO 639-1) for the DerivAPI server
ws *websocket.Conn // The WebSocket connection to the DerivAPI server
lastRequestID int64 // The last request ID used for the DerivAPI server
TimeOut time.Duration // The timeout duration for the DerivAPI server api calls
connectionLock sync.Mutex // A lock for the DerivAPI server connection
reqChan chan ApiReqest // A channel for sending requests to the DerivAPI server
closingChan chan int // A channel for closing the DerivAPI server connection
keepAlive bool // A flag to keep the connection alive
keepAliveOnDisconnect chan bool // A channel to keep the connection alive
keepAliveInterval time.Duration // The interval to send ping requests
debugEnabled bool // A flag to print debug messages
type DerivAPI struct { //nolint:revive // don't want to change the name for now
reqChan chan APIReqest
Endpoint *url.URL
keepAliveOnDisconnect chan bool
Origin *url.URL
ws *websocket.Conn
closingChan chan int
Lang string
TimeOut time.Duration
lastRequestID int64
AppID int
keepAliveInterval time.Duration
connectionLock sync.Mutex
keepAlive bool
debugEnabled bool
}

// ApiReqest is an interface for all API requests.
type ApiReqest struct {
id int
msg []byte
// APIReqest is an interface for all API requests.
type APIReqest struct {
respChan chan []byte
msg []byte
id int
}

type APIResponseReqID struct {
ReqID int `json:"req_id"`
}

type DerivApiOption func(api *DerivAPI)
type APIOption func(api *DerivAPI)

// NewDerivAPI creates a new instance of DerivAPI by parsing and validating the given
// endpoint URL, appID, language, and origin URL. It returns a pointer to a DerivAPI object
Expand All @@ -56,9 +62,9 @@ type DerivApiOption func(api *DerivAPI)
// - appID: int - The app ID for the DerivAPI server
// - lang: string - The language code (ISO 639-1) for the DerivAPI server
// - origin: string - The origin URL for the DerivAPI server
// - opts: DerivApiOption - A variadic list of DerivApiOption functions to configure the DerivAPI object (optional)
// - KeepAlive: A DerivApiOption function to keep the connection alive by sending ping requests.
// - Debug: A DerivApiOption function to enable debug messages.
// - opts: APIOption - A variadic list of APIOption functions to configure the DerivAPI object (optional)
// - KeepAlive: A APIOption function to keep the connection alive by sending ping requests.
// - Debug: A APIOption function to enable debug messages.
//
// Returns:
// - *DerivAPI: A pointer to a new instance of DerivAPI with the validated endpoint, appID,
Expand All @@ -71,7 +77,7 @@ type DerivApiOption func(api *DerivAPI)
// if err != nil {
// log.Fatal(err)
// }
func NewDerivAPI(endpoint string, appID int, lang string, origin string, opts ...DerivApiOption) (*DerivAPI, error) {
func NewDerivAPI(endpoint string, appID int, lang, origin string, opts ...APIOption) (*DerivAPI, error) {
urlEnpoint, err := url.Parse(endpoint)
if err != nil {
return nil, err
Expand All @@ -91,7 +97,7 @@ func NewDerivAPI(endpoint string, appID int, lang string, origin string, opts ..
}

if lang == "" || len(lang) != 2 {
return nil, fmt.Errorf("Invalid language")
return nil, fmt.Errorf("invalid language")
}

query := urlEnpoint.Query()
Expand All @@ -106,10 +112,10 @@ func NewDerivAPI(endpoint string, appID int, lang string, origin string, opts ..
AppID: appID,
Lang: lang,
lastRequestID: 0,
TimeOut: 30 * time.Second,
TimeOut: defaultTimeout,
connectionLock: sync.Mutex{},
closingChan: make(chan int),
keepAliveInterval: 25 * time.Second,
keepAliveInterval: keepAliveInterval,
}

for _, opt := range opts {
Expand Down Expand Up @@ -167,7 +173,7 @@ func (api *DerivAPI) Connect() error {

api.ws = ws

api.reqChan = make(chan ApiReqest)
api.reqChan = make(chan APIReqest)
respChan := make(chan []byte)
outputChan := make(chan []byte)

Expand All @@ -189,7 +195,6 @@ func (api *DerivAPI) Connect() error {
case <-onDisconnect:
return
}

}
}(api.keepAliveInterval, api.keepAliveOnDisconnect)
}
Expand Down Expand Up @@ -229,11 +234,10 @@ func (api *DerivAPI) requestSender(wsConn *websocket.Conn, reqChan chan []byte)
for req := range reqChan {
api.logDebugf("Sending request: %s", req)

err := wsConn.Write(context.TODO(), websocket.MessageText, req)

if err != nil {
if err := wsConn.Write(context.TODO(), websocket.MessageText, req); err != nil {
api.logDebugf("Failed to send request: %s", err.Error())
api.Disconnect()

return
}
}
Expand Down Expand Up @@ -277,7 +281,7 @@ func (api *DerivAPI) handleResponses(wsConn *websocket.Conn, respChan chan []byt

// requestMapper forward requests to the Deriv API server and
// responses from the WebSocket server to the appropriate channels.
func (api *DerivAPI) requestMapper(respChan chan []byte, outputChan chan []byte, reqChan chan ApiReqest, closingChan chan int) {
func (api *DerivAPI) requestMapper(respChan, outputChan chan []byte, reqChan chan APIReqest, closingChan chan int) {
responseMap := make(map[int]chan []byte)

defer func() {
Expand All @@ -291,29 +295,26 @@ func (api *DerivAPI) requestMapper(respChan chan []byte, outputChan chan []byte,
select {
case rawResp := <-respChan:
var response APIResponseReqID
err := json.Unmarshal(rawResp, &response)
if err != nil {

if err := json.Unmarshal(rawResp, &response); err != nil {
continue
}
channel, ok := responseMap[response.ReqID]

if ok {
if channel, ok := responseMap[response.ReqID]; ok {
channel <- rawResp
}
case req, ok := <-reqChan:
if !ok {
return
}

responseMap[req.id] = req.respChan
outputChan <- req.msg
case reqID := <-closingChan:
channel, okGet := responseMap[reqID]

if okGet {
if channel, ok := responseMap[reqID]; ok {
close(channel)
delete(responseMap, reqID)
}

}
}
}
Expand All @@ -333,19 +334,19 @@ func (api *DerivAPI) Send(reqID int, request any) (chan []byte, error) {

respChan := make(chan []byte)

ApiReqest := ApiReqest{
req := APIReqest{
id: reqID,
msg: msg,
respChan: respChan,
}

api.reqChan <- ApiReqest
api.reqChan <- req

return respChan, nil
}

// SendRequest sends a request to the Deriv API and returns the response
func (api *DerivAPI) SendRequest(reqID int, request any, response any) (err error) {
func (api *DerivAPI) SendRequest(reqID int, request, response any) error {
respChan, err := api.Send(reqID, request)

if err != nil {
Expand All @@ -364,18 +365,16 @@ func (api *DerivAPI) SendRequest(reqID int, request any, response any) (err erro
return fmt.Errorf("connection closed")
}

if err = parseError(responseJSON); err != nil {
if err := parseError(responseJSON); err != nil {
return err
}

err = json.Unmarshal(responseJSON, response)
if err != nil {
if err := json.Unmarshal(responseJSON, response); err != nil {
api.logDebugf("Failed to parse response for request %d: %s", reqID, err.Error())
return err
}

return nil

}
}

Expand Down
Loading

0 comments on commit 854eb1f

Please sign in to comment.