tracked_subscription.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package subscriptionmanager
  2. import (
  3. "time"
  4. "github.com/v2fly/v2ray-core/v5/app/subscription"
  5. "github.com/v2fly/v2ray-core/v5/app/subscription/containers"
  6. "github.com/v2fly/v2ray-core/v5/app/subscription/specs"
  7. )
  8. func newTrackedSubscription(importSource *subscription.ImportSource) (*trackedSubscription, error) { //nolint: unparam
  9. return &trackedSubscription{importSource: importSource, materialized: map[string]*materializedServer{}}, nil
  10. }
  11. type trackedSubscription struct {
  12. importSource *subscription.ImportSource
  13. currentDocumentExpireTime time.Time
  14. currentDocument *specs.SubscriptionDocument
  15. materialized map[string]*materializedServer
  16. originalDocument []byte
  17. originalContainer *containers.Container
  18. originalServerConfig map[string]*originalServerConfig
  19. addedByAPI bool
  20. }
  21. type originalServerConfig struct {
  22. data []byte
  23. }
  24. func (s *trackedSubscription) diff(newDocument *specs.SubscriptionDocument) (changedDocument, error) { //nolint: unparam
  25. delta := changedDocument{}
  26. seen := make(map[string]bool)
  27. for _, server := range newDocument.Server {
  28. if currentMaterialized, found := s.materialized[server.Id]; found {
  29. if currentMaterialized.serverConfig.Metadata[ServerMetadataFullyQualifiedName] == server.Metadata[ServerMetadataFullyQualifiedName] {
  30. delta.unchanged = append(delta.unchanged, server.Id)
  31. } else {
  32. delta.modified = append(delta.modified, server.Id)
  33. }
  34. seen[server.Id] = true
  35. } else {
  36. delta.added = append(delta.added, server.Id)
  37. }
  38. }
  39. for name := range s.materialized {
  40. if _, ok := seen[name]; !ok {
  41. delta.removed = append(delta.removed, name)
  42. }
  43. }
  44. return delta, nil
  45. }
  46. func (s *trackedSubscription) recordRemovedServer(name string) {
  47. delete(s.materialized, name)
  48. }
  49. func (s *trackedSubscription) recordUpdatedServer(name, tagPostfix string, serverConfig *specs.SubscriptionServerConfig) {
  50. s.materialized[name] = &materializedServer{tagPostfix: tagPostfix, serverConfig: serverConfig}
  51. }
  52. func (s *trackedSubscription) getCurrentServer(name string) (*materializedServer, error) {
  53. if materialized, found := s.materialized[name]; found {
  54. return materialized, nil
  55. } else {
  56. return nil, newError("not found")
  57. }
  58. }
  59. type materializedServer struct {
  60. tagPostfix string
  61. serverConfig *specs.SubscriptionServerConfig
  62. }
  63. func (s *trackedSubscription) fillStatus(status *subscription.TrackedSubscriptionStatus) error { //nolint: unparam
  64. status.ImportSource = s.importSource
  65. if s.currentDocument == nil {
  66. return nil
  67. }
  68. status.DocumentMetadata = s.currentDocument.Metadata
  69. status.Servers = make(map[string]*subscription.SubscriptionServer)
  70. for _, v := range s.currentDocument.Server {
  71. status.Servers[v.Id] = &subscription.SubscriptionServer{
  72. ServerMetadata: v.Metadata,
  73. }
  74. if materializedInstance, ok := s.materialized[v.Id]; ok {
  75. status.Servers[v.Id].Tag = materializedInstance.tagPostfix
  76. }
  77. }
  78. status.AddedByApi = s.addedByAPI
  79. return nil
  80. }