github.com/moleculer-go/moleculer@v0.3.3/transit/memory/memory.go (about)

     1  package memory
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"github.com/moleculer-go/moleculer"
     8  	"github.com/moleculer-go/moleculer/serializer"
     9  	"github.com/moleculer-go/moleculer/transit"
    10  	"github.com/moleculer-go/moleculer/util"
    11  	log "github.com/sirupsen/logrus"
    12  )
    13  
    14  type Subscription struct {
    15  	id            string
    16  	transporterId string
    17  	handler       transit.TransportHandler
    18  	active        bool
    19  }
    20  
    21  type SharedMemory struct {
    22  	handlers map[string][]Subscription
    23  	mutex    *sync.Mutex
    24  }
    25  
    26  type MemoryTransporter struct {
    27  	prefix     string
    28  	instanceID string
    29  	logger     *log.Entry
    30  	memory     *SharedMemory
    31  }
    32  
    33  func Create(logger *log.Entry, memory *SharedMemory) MemoryTransporter {
    34  	instanceID := util.RandomString(5)
    35  	if memory.handlers == nil {
    36  		memory.handlers = make(map[string][]Subscription)
    37  	}
    38  	if memory.mutex == nil {
    39  		memory.mutex = &sync.Mutex{}
    40  	}
    41  	return MemoryTransporter{memory: memory, logger: logger, instanceID: instanceID}
    42  }
    43  
    44  func (transporter *MemoryTransporter) SetPrefix(prefix string) {
    45  	transporter.prefix = prefix
    46  }
    47  
    48  func (transporter *MemoryTransporter) SetNodeID(nodeID string) {
    49  }
    50  
    51  func (transporter *MemoryTransporter) SetSerializer(serializer serializer.Serializer) {
    52  
    53  }
    54  
    55  func (transporter *MemoryTransporter) Connect() chan error {
    56  	transporter.logger.Debug("[Mem-Trans-", transporter.instanceID, "] -> Connecting() ...")
    57  	endChan := make(chan error)
    58  	go func() {
    59  		endChan <- nil
    60  	}()
    61  	transporter.logger.Info("[Mem-Trans-", transporter.instanceID, "] -> Connected() !")
    62  	return endChan
    63  }
    64  
    65  func (transporter *MemoryTransporter) Disconnect() chan error {
    66  	endChan := make(chan error)
    67  	transporter.logger.Debug("[Mem-Trans-", transporter.instanceID, "] -> Disconnecting() ...")
    68  
    69  	newHandlers := map[string][]Subscription{}
    70  	for key, subscriptions := range transporter.memory.handlers {
    71  		keep := []Subscription{}
    72  		for _, subscription := range subscriptions {
    73  			if subscription.transporterId != transporter.instanceID {
    74  				keep = append(keep, subscription)
    75  			}
    76  		}
    77  		newHandlers[key] = keep
    78  	}
    79  	transporter.memory.handlers = newHandlers
    80  
    81  	go func() {
    82  		endChan <- nil
    83  	}()
    84  	transporter.logger.Info("[Mem-Trans-", transporter.instanceID, "] -> Disconnected() !")
    85  	return endChan
    86  }
    87  
    88  func topicName(transporter *MemoryTransporter, command string, nodeID string) string {
    89  	if nodeID != "" {
    90  		return fmt.Sprint(transporter.prefix, ".", command, ".", nodeID)
    91  	}
    92  	return fmt.Sprint(transporter.prefix, ".", command)
    93  }
    94  
    95  func (transporter *MemoryTransporter) Subscribe(command string, nodeID string, handler transit.TransportHandler) {
    96  	topic := topicName(transporter, command, nodeID)
    97  	transporter.logger.Trace("[Mem-Trans-", transporter.instanceID, "] Subscribe() listen for command: ", command, " nodeID: ", nodeID, " topic: ", topic)
    98  
    99  	subscription := Subscription{util.RandomString(5) + "_" + command, transporter.instanceID, handler, true}
   100  
   101  	transporter.memory.mutex.Lock()
   102  	_, exists := transporter.memory.handlers[topic]
   103  	if exists {
   104  		transporter.memory.handlers[topic] = append(transporter.memory.handlers[topic], subscription)
   105  	} else {
   106  		transporter.memory.handlers[topic] = []Subscription{subscription}
   107  	}
   108  	transporter.memory.mutex.Unlock()
   109  }
   110  
   111  func (transporter *MemoryTransporter) Publish(command, nodeID string, message moleculer.Payload) {
   112  	topic := topicName(transporter, command, nodeID)
   113  	transporter.logger.Trace("[Mem-Trans-", transporter.instanceID, "] Publish() command: ", command, " nodeID: ", nodeID, " message: \n", message, "\n - end")
   114  
   115  	transporter.memory.mutex.Lock()
   116  	subscriptions, exists := transporter.memory.handlers[topic]
   117  	transporter.memory.mutex.Unlock()
   118  	if exists {
   119  		for _, subscription := range subscriptions {
   120  			if subscription.active {
   121  				go subscription.handler(message)
   122  			}
   123  		}
   124  	}
   125  }