1
0
mirror of https://github.com/ManyakRus/starter.git synced 2025-11-25 23:02:22 +02:00
Files
starter/tinkoff_connect/tinkoff_connect.go

273 lines
6.7 KiB
Go
Raw Normal View History

2024-11-19 11:36:44 +03:00
package tinkoff_connect
import (
"context"
"errors"
"github.com/ManyakRus/starter/contextmain"
"github.com/ManyakRus/starter/log"
"github.com/ManyakRus/starter/microl"
"github.com/ManyakRus/starter/port_checker"
"github.com/ManyakRus/starter/stopapp"
"github.com/tinkoff/invest-api-go-sdk/investgo"
"os"
"sync"
"time"
)
// SettingsINI - тип для хранения настроек подключени
type SettingsINI struct {
investgo.Config
Host string
Port string
}
// Settings - структура для хранения настроек подключения
var Settings SettingsINI
2025-05-14 16:03:45 +03:00
// Conn - подключение к серверу Tinkoff-GRPC
2024-11-19 12:43:10 +03:00
var Client *investgo.Client
2024-11-19 11:36:44 +03:00
// mutex_Connect - защита от многопоточности Reconnect()
2025-05-14 10:30:09 +03:00
var mutex_Connect = &sync.RWMutex{}
2024-11-19 11:36:44 +03:00
// NeedReconnect - флаг необходимости переподключения
var NeedReconnect bool
// timeoutSeconds - время ожидания запроса в Тинькофф, в секундах
var timeoutSeconds = 60
2025-05-14 10:30:09 +03:00
// GetConnection - возвращает соединение
func GetConnection() *investgo.Client {
//мьютекс чтоб не подключаться одновременно
mutex_Connect.RLock()
defer mutex_Connect.RUnlock()
2025-05-14 16:10:09 +03:00
//
2025-05-14 10:30:09 +03:00
if Client == nil {
err := Connect_err()
LogInfo_Connected(err)
}
return Client
}
2025-05-14 16:03:45 +03:00
// Connect - подключается к серверу Tinkoff-GRPC, при ошибке вызывает панику
2024-11-19 11:36:44 +03:00
func Connect() {
var err error
err = Connect_err()
2025-05-14 10:30:09 +03:00
LogInfo_Connected_Panic(err)
}
// LogInfo_Connected - выводит сообщение в Лог
func LogInfo_Connected(err error) {
2024-11-19 11:36:44 +03:00
if err != nil {
2025-05-14 10:30:09 +03:00
log.Errorf("Tinkoff connection ERROR. EndPoint: %s, AccountId: %s, error: %s", Settings.EndPoint, Settings.AccountId, err)
2024-11-19 11:36:44 +03:00
} else {
2025-05-14 10:30:09 +03:00
log.Infof("Tinkoff connection OK. EndPoint: %s, AccountId: %s", Settings.EndPoint, Settings.AccountId)
2024-11-19 11:36:44 +03:00
}
}
2025-05-14 10:30:09 +03:00
// LogInfo_Connected_Panic - выводит сообщение в Лог или панику
func LogInfo_Connected_Panic(err error) {
LogInfo_Connected(err)
if err != nil {
panic(err)
}
}
2025-05-14 16:03:45 +03:00
// Connect_err - подключается к серверу Tinkoff-GRPC, возвращает ошибку
2024-11-19 11:36:44 +03:00
func Connect_err() error {
var err error
2025-05-14 10:30:09 +03:00
//мьютекс чтоб не подключаться одновременно
2024-11-19 11:36:44 +03:00
mutex_Connect.Lock()
defer mutex_Connect.Unlock()
//
if Settings.EndPoint == "" {
err = FillSettings()
if err != nil {
return err
}
}
ctx := contextmain.GetContext()
//addr := Settings.Host + ":" + Settings.Port
2024-11-19 12:43:10 +03:00
Config := Settings.Config
Client, err = investgo.NewClient(ctx, Config, log.GetLog())
2024-11-19 11:36:44 +03:00
if err != nil {
return err
}
return err
}
func FillSettings() error {
var err error
Settings = SettingsINI{}
INVEST_HOST := os.Getenv("INVEST_HOST")
INVEST_PORT := os.Getenv("INVEST_PORT")
Settings.Host = INVEST_HOST
Settings.Port = INVEST_PORT
EndPoint := INVEST_HOST + ":" + INVEST_PORT
Settings.EndPoint = EndPoint
if INVEST_HOST == "" {
TextError := "Need fill INVEST_HOST ! in OS Environment "
err = errors.New(TextError)
return err
}
if INVEST_PORT == "" {
TextError := "Need fill INVEST_PORT ! in OS Environment "
err = errors.New(TextError)
return err
}
Name := ""
s := ""
//
Name = "INVEST_TOKEN"
s = microl.Getenv(Name, true)
Settings.Token = s
//
Name = "INVEST_ACCOUNTID"
2024-12-02 14:23:21 +03:00
s = microl.Getenv(Name, false)
2024-11-19 11:36:44 +03:00
Settings.AccountId = s
return err
}
// WaitStop - ожидает отмену глобального контекста
func WaitStop() {
defer stopapp.GetWaitGroup_Main().Done()
2024-11-19 11:36:44 +03:00
select {
case <-contextmain.GetContext().Done():
2025-05-14 16:03:45 +03:00
log.Warn("Context app is canceled. tinkoff_connect")
2024-11-19 11:36:44 +03:00
}
// ждём пока отправляемых сейчас сообщений будет =0
2025-01-16 14:28:59 +03:00
stopapp.WaitTotalMessagesSendingNow("tinkoff_connect")
2024-11-19 11:36:44 +03:00
// закрываем соединение
CloseConnection()
}
2025-05-14 16:03:45 +03:00
// Start - необходимые процедуры для запуска сервера Tinkoff-GRPC
2024-11-19 11:36:44 +03:00
// если контекст хранится в contextmain.GetContext()
// и есть stopapp.GetWaitGroup_Main()
// при ошибке вызывает панику
func Start() {
Connect()
stopapp.GetWaitGroup_Main().Add(1)
go WaitStop()
stopapp.GetWaitGroup_Main().Add(1)
go ping_go()
}
2025-05-14 16:03:45 +03:00
// Start_ctx - необходимые процедуры для запуска сервера Tinkoff-GRPC
2024-11-19 11:36:44 +03:00
// ctx - глобальный контекст приложения
// wg - глобальный WaitGroup приложения
func Start_ctx(ctx *context.Context, wg *sync.WaitGroup) error {
var err error
if contextmain.Ctx != ctx {
contextmain.SetContext(ctx)
}
//contextmain.Ctx = ctx
2024-11-19 11:36:44 +03:00
stopapp.SetWaitGroup_Main(wg)
err = Connect_err()
if err != nil {
return err
}
stopapp.GetWaitGroup_Main().Add(1)
go WaitStop()
stopapp.GetWaitGroup_Main().Add(1)
go ping_go()
return err
}
2025-05-14 16:03:45 +03:00
// CloseConnection - закрывает подключение к Tinkoff-GRPC, и пишет лог
2024-11-19 11:36:44 +03:00
func CloseConnection() {
err := CloseConnection_err()
if err != nil {
2025-05-14 16:03:45 +03:00
log.Error("tinkoff_connect client CloseConnection() error: ", err)
2024-11-19 11:36:44 +03:00
} else {
2025-05-14 16:03:45 +03:00
log.Info("tinkoff_connect client connection closed")
2024-11-19 11:36:44 +03:00
}
}
2025-05-14 16:03:45 +03:00
// CloseConnection - закрывает подключение к Tinkoff-GRPC, и возвращает ошибку
2024-11-19 11:36:44 +03:00
func CloseConnection_err() error {
2024-11-19 12:43:10 +03:00
err := Client.Stop()
2024-11-19 11:36:44 +03:00
return err
}
// ping_go - делает пинг каждые 60 секунд, и реконнект
func ping_go() {
2025-04-01 16:02:24 +03:00
var err error
2024-11-19 11:36:44 +03:00
defer stopapp.GetWaitGroup_Main().Done()
2024-11-19 11:36:44 +03:00
ticker := time.NewTicker(60 * time.Second)
defer ticker.Stop()
addr := Settings.Host + ":" + Settings.Port
//бесконечный цикл
loop:
for {
select {
case <-contextmain.GetContext().Done():
2025-05-14 16:03:45 +03:00
log.Warn("Context app is canceled. tinkoff_connect.ping")
2024-11-19 11:36:44 +03:00
break loop
case <-ticker.C:
2025-04-01 16:02:24 +03:00
err = port_checker.CheckPort_err(Settings.Host, Settings.Port)
2024-11-19 11:36:44 +03:00
//log.Debug("ticker, ping err: ", err) //удалить
if err != nil {
NeedReconnect = true
2025-05-14 16:03:45 +03:00
log.Warn("tinkoff_connect CheckPort(", addr, ") error: ", err)
2024-11-19 11:36:44 +03:00
} else if NeedReconnect == true {
2025-05-14 16:03:45 +03:00
log.Warn("tinkoff_connect CheckPort(", addr, ") OK. Start Reconnect()")
2024-11-19 11:36:44 +03:00
NeedReconnect = false
err = Connect_err()
2025-05-14 10:30:09 +03:00
LogInfo_Connected(err)
2024-11-19 11:36:44 +03:00
if err != nil {
NeedReconnect = true
2025-05-14 16:03:45 +03:00
//log.Error("tinkoff_connect Connect() error: ", err)
2024-11-19 11:36:44 +03:00
}
}
}
}
}
// GetTimeoutSeconds - возвращает время ожидания ответа
func GetTimeoutSeconds() int {
Otvet := timeoutSeconds
return Otvet
}
// SetTimeoutSeconds - устанавливает время ожидания ответа
func SetTimeoutSeconds(seconds int) {
timeoutSeconds = seconds
}