manager.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package runtime
  2. import (
  3. "errors"
  4. "sync"
  5. "github.com/mhsanaei/3x-ui/v3/internal/database"
  6. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  7. )
  8. type NodeEgressResolver interface {
  9. NodeEgressProxyURL(nodeID int) string
  10. }
  11. type Manager struct {
  12. local Runtime
  13. mu sync.RWMutex
  14. remotes map[int]*Remote
  15. egressResolver NodeEgressResolver
  16. }
  17. func NewManager(localDeps LocalDeps) *Manager {
  18. return &Manager{
  19. local: NewLocal(localDeps),
  20. remotes: make(map[int]*Remote),
  21. }
  22. }
  23. func (m *Manager) SetNodeEgressResolver(r NodeEgressResolver) {
  24. m.mu.Lock()
  25. defer m.mu.Unlock()
  26. m.egressResolver = r
  27. }
  28. func (m *Manager) NodeEgressProxyURL(nodeID int) string {
  29. m.mu.RLock()
  30. defer m.mu.RUnlock()
  31. if m.egressResolver == nil {
  32. return ""
  33. }
  34. return m.egressResolver.NodeEgressProxyURL(nodeID)
  35. }
  36. func (m *Manager) RuntimeFor(nodeID *int) (Runtime, error) {
  37. if nodeID == nil {
  38. return m.local, nil
  39. }
  40. m.mu.RLock()
  41. if rt, ok := m.remotes[*nodeID]; ok {
  42. m.mu.RUnlock()
  43. return rt, nil
  44. }
  45. m.mu.RUnlock()
  46. m.mu.Lock()
  47. defer m.mu.Unlock()
  48. if rt, ok := m.remotes[*nodeID]; ok {
  49. return rt, nil
  50. }
  51. n, err := loadNode(*nodeID)
  52. if err != nil {
  53. return nil, err
  54. }
  55. if !n.Enable {
  56. return nil, errors.New("node " + n.Name + " is disabled")
  57. }
  58. rt := NewRemote(n, m.egressResolver)
  59. m.remotes[*nodeID] = rt
  60. return rt, nil
  61. }
  62. func (m *Manager) Local() Runtime { return m.local }
  63. func (m *Manager) RemoteFor(node *model.Node) (*Remote, error) {
  64. if node == nil {
  65. return nil, errors.New("node is nil")
  66. }
  67. m.mu.RLock()
  68. if rt, ok := m.remotes[node.Id]; ok {
  69. m.mu.RUnlock()
  70. return rt, nil
  71. }
  72. m.mu.RUnlock()
  73. m.mu.Lock()
  74. defer m.mu.Unlock()
  75. if rt, ok := m.remotes[node.Id]; ok {
  76. return rt, nil
  77. }
  78. rt := NewRemote(node, m.egressResolver)
  79. m.remotes[node.Id] = rt
  80. return rt, nil
  81. }
  82. func (m *Manager) InvalidateNode(nodeID int) {
  83. m.mu.Lock()
  84. defer m.mu.Unlock()
  85. delete(m.remotes, nodeID)
  86. }
  87. func loadNode(id int) (*model.Node, error) {
  88. db := database.GetDB()
  89. n := &model.Node{}
  90. if err := db.Model(model.Node{}).Where("id = ?", id).First(n).Error; err != nil {
  91. return nil, err
  92. }
  93. return n, nil
  94. }
  95. var (
  96. managerMu sync.RWMutex
  97. manager *Manager
  98. )
  99. func SetManager(m *Manager) {
  100. managerMu.Lock()
  101. defer managerMu.Unlock()
  102. manager = m
  103. }
  104. func GetManager() *Manager {
  105. managerMu.RLock()
  106. defer managerMu.RUnlock()
  107. return manager
  108. }