Files
futriix/internal/cluster/types.go

240 lines
8.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright 2026 Safronov Grigorii
*
* Licensed under the CDDL, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* https://opensource.org/licenses/CDDL-1.0
*/
// Файл: internal/cluster/types.go
// Назначение: Общие типы данных для кластерных операций с поддержкой временных меток
// NOTE: NodeInfo, NodeRequest, ShardInfo, ClusterStatus определены в node.go и raft_coordinator.go
// Чтобы избежать дублирования, здесь определяем только вспомогательные типы и функции
package cluster
import (
"fmt"
"time"
)
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ДЛЯ NodeInfo ==========
// NodeJoinedAt возвращает человекочитаемое время присоединения узла
func NodeJoinedAt(joinedAt int64) string {
if joinedAt == 0 {
return "not joined"
}
return time.UnixMilli(joinedAt).Format("2006-01-02 15:04:05.000")
}
// LastSeenAt возвращает человекочитаемое время последнего контакта
func LastSeenAt(lastSeen int64) string {
if lastSeen == 0 {
return "never"
}
return time.UnixMilli(lastSeen).Format("2006-01-02 15:04:05.000")
}
// GetNodeUptime возвращает время жизни узла в кластере
func GetNodeUptime(joinedAt int64) time.Duration {
if joinedAt == 0 {
return 0
}
return time.Duration(time.Now().UnixMilli()-joinedAt) * time.Millisecond
}
// IsNodeHealthy проверяет, здоров ли узел
func IsNodeHealthy(status string, lastSeen int64) bool {
return status == "active" && time.Now().UnixMilli()-lastSeen < 30000
}
// GetNodeAddress возвращает адрес узла
func GetNodeAddress(ip string, port int) string {
return fmt.Sprintf("%s:%d", ip, port)
}
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ДЛЯ ShardInfo ==========
// GetShardUptime возвращает время жизни шарда
func GetShardUptime(createdAt int64) time.Duration {
if createdAt == 0 {
return 0
}
return time.Duration(time.Now().UnixMilli()-createdAt) * time.Millisecond
}
// IsShardHealthy проверяет, здоров ли шард
func IsShardHealthy(status string) bool {
return status == "active"
}
// GetShardLastRebalancedStr возвращает человекочитаемое время последней ребалансировки
func GetShardLastRebalancedStr(lastRebalanced int64) string {
if lastRebalanced == 0 {
return "never"
}
return time.UnixMilli(lastRebalanced).Format("2006-01-02 15:04:05.000")
}
// GetShardCreatedAtStr возвращает человекочитаемое время создания
func GetShardCreatedAtStr(createdAt int64) string {
if createdAt == 0 {
return "unknown"
}
return time.UnixMilli(createdAt).Format("2006-01-02 15:04:05.000")
}
// GetShardUpdatedAtStr возвращает человекочитаемое время обновления
func GetShardUpdatedAtStr(updatedAt int64) string {
if updatedAt == 0 {
return "unknown"
}
return time.UnixMilli(updatedAt).Format("2006-01-02 15:04:05.000")
}
// GetShardLeaderNode возвращает лидера шарда
func GetShardLeaderNode(leaderNode string) string {
return leaderNode
}
// GetShardNodeCount возвращает количество узлов в шарде
func GetShardNodeCount(nodes []string) int {
return len(nodes)
}
// GetShardReplicationFactor возвращает фактор репликации шарда
func GetShardReplicationFactor(nodes []string) int {
return len(nodes)
}
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ДЛЯ ReplicationLogEntry ==========
// GetReplicationTimestampStr возвращает человекочитаемое время записи репликации
func GetReplicationTimestampStr(timestamp int64) string {
if timestamp == 0 {
return "unknown"
}
return time.UnixMilli(timestamp).Format("2006-01-02 15:04:05.000")
}
// IsReplicationSuccess проверяет, успешна ли операция репликации
func IsReplicationSuccess(status string) bool {
return status == "success"
}
// GetReplicationDuration возвращает длительность операции
func GetReplicationDuration(durationMs int64) time.Duration {
return time.Duration(durationMs) * time.Millisecond
}
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ДЛЯ ClusterHealth ==========
// IsClusterHealthy проверяет, здоров ли кластер в целом
func IsClusterHealthy(overallScore float64) bool {
return overallScore >= 80
}
// IsClusterDegraded проверяет, деградирован ли кластер
func IsClusterDegraded(overallScore float64) bool {
return overallScore >= 50 && overallScore < 80
}
// IsClusterCritical проверяет, находится ли кластер в критическом состоянии
func IsClusterCritical(overallScore float64) bool {
return overallScore < 50
}
// GetHealthyNodesCount возвращает количество здоровых узлов
func GetHealthyNodesCount(nodes map[string]*NodeHealth) int {
if nodes == nil {
return 0
}
count := 0
for _, node := range nodes {
if node.Status == "active" {
count++
}
}
return count
}
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ==========
// GetTimestamp возвращает текущий timestamp в миллисекундах
func GetTimestamp() int64 {
return time.Now().UnixMilli()
}
// FormatTimestamp форматирует timestamp в человекочитаемый вид
func FormatTimestamp(ts int64) string {
if ts == 0 {
return "never"
}
return time.UnixMilli(ts).Format("2006-01-02 15:04:05.000")
}
// IsTimestampExpired проверяет, истёк ли timestamp
func IsTimestampExpired(ts int64, ttl time.Duration) bool {
if ts == 0 {
return true
}
return time.Now().UnixMilli()-ts > ttl.Milliseconds()
}
// ========== ТИПЫ, КОТОРЫЕ НЕ ДУБЛИРУЮТСЯ В ДРУГИХ ФАЙЛАХ ==========
// NodeHealth представляет здоровье отдельного узла
type NodeHealth struct {
Status string `json:"status"`
LatencyMs int64 `json:"latency_ms"`
LastCheck int64 `json:"last_check"`
LastSuccess int64 `json:"last_success"`
LastFailure int64 `json:"last_failure"`
FailureCount int `json:"failure_count"`
}
// ClusterHealth представляет информацию о здоровье кластера
type ClusterHealth struct {
Nodes map[string]*NodeHealth `json:"nodes"`
OverallScore float64 `json:"overall_score"`
Recommendations string `json:"recommendations"`
CheckedAt int64 `json:"checked_at"`
}
// ConnectionInfo содержит информацию о соединении с узлом
type ConnectionInfo struct {
NodeID string `json:"node_id"`
Address string `json:"address"`
IsHealthy bool `json:"is_healthy"`
LastUsed int64 `json:"last_used"`
Failures uint32 `json:"failures"`
ConnectedAt int64 `json:"connected_at"`
}
// ClusterOperation представляет операцию в кластере
type ClusterOperation struct {
ID string `json:"id"`
Type string `json:"type"`
Status string `json:"status"`
CreatedAt int64 `json:"created_at"`
StartedAt int64 `json:"started_at"`
CompletedAt int64 `json:"completed_at"`
Details map[string]interface{} `json:"details"`
Error string `json:"error,omitempty"`
}
// WorkerPoolStats содержит статистику пула воркеров
type WorkerPoolStats struct {
MaxWorkers int `json:"max_workers"`
ActiveTasks int32 `json:"active_tasks"`
TotalTasks uint64 `json:"total_tasks"`
FailedTasks uint64 `json:"failed_tasks"`
QueueSize int `json:"queue_size"`
QueueCapacity int `json:"queue_capacity"`
}