github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/app/subscription/subscriptionmanager/tracked_subscription.go (about)

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