github.com/anuvu/tyk@v2.9.0-beta9-dl-apic+incompatible/gateway/distributed_rate_limiter.go (about)

     1  package gateway
     2  
     3  import (
     4  	"encoding/json"
     5  	"time"
     6  
     7  	"github.com/sirupsen/logrus"
     8  
     9  	"github.com/TykTechnologies/drl"
    10  	"github.com/TykTechnologies/tyk/config"
    11  )
    12  
    13  var DRLManager = &drl.DRL{}
    14  
    15  func setupDRL() {
    16  	drlManager := &drl.DRL{}
    17  	drlManager.Init()
    18  	drlManager.ThisServerID = getNodeID() + "|" + hostDetails.Hostname
    19  	log.Debug("DRL: Setting node ID: ", drlManager.ThisServerID)
    20  	DRLManager = drlManager
    21  }
    22  
    23  func startRateLimitNotifications() {
    24  	notificationFreq := config.Global().DRLNotificationFrequency
    25  	if notificationFreq == 0 {
    26  		notificationFreq = 2
    27  	}
    28  
    29  	go func() {
    30  		log.Info("Starting gateway rate limiter notifications...")
    31  		for {
    32  			if getNodeID() != "" {
    33  				NotifyCurrentServerStatus()
    34  			} else {
    35  				log.Warning("Node not registered yet, skipping DRL Notification")
    36  			}
    37  
    38  			time.Sleep(time.Duration(notificationFreq) * time.Second)
    39  		}
    40  	}()
    41  }
    42  
    43  func getTagHash() string {
    44  	th := ""
    45  	for _, tag := range config.Global().DBAppConfOptions.Tags {
    46  		th += tag
    47  	}
    48  	return th
    49  }
    50  
    51  func NotifyCurrentServerStatus() {
    52  	if !DRLManager.Ready {
    53  		return
    54  	}
    55  
    56  	rate := GlobalRate.Rate()
    57  	if rate == 0 {
    58  		rate = 1
    59  	}
    60  
    61  	server := drl.Server{
    62  		HostName:   hostDetails.Hostname,
    63  		ID:         getNodeID(),
    64  		LoadPerSec: rate,
    65  		TagHash:    getTagHash(),
    66  	}
    67  
    68  	asJson, err := json.Marshal(server)
    69  	if err != nil {
    70  		log.Error("Failed to encode payload: ", err)
    71  		return
    72  	}
    73  
    74  	n := Notification{
    75  		Command: NoticeGatewayDRLNotification,
    76  		Payload: string(asJson),
    77  	}
    78  
    79  	MainNotifier.Notify(n)
    80  }
    81  
    82  func onServerStatusReceivedHandler(payload string) {
    83  	serverData := drl.Server{}
    84  	if err := json.Unmarshal([]byte(payload), &serverData); err != nil {
    85  		log.WithFields(logrus.Fields{
    86  			"prefix": "pub-sub",
    87  		}).Error("Failed unmarshal server data: ", err)
    88  		return
    89  	}
    90  
    91  	log.Debug("Received DRL data: ", serverData)
    92  
    93  	if DRLManager.Ready {
    94  		if err := DRLManager.AddOrUpdateServer(serverData); err != nil {
    95  			log.WithError(err).
    96  				WithField("serverData", serverData).
    97  				Debug("AddOrUpdateServer error. Seems like you running multiple segmented Tyk groups in same Redis.")
    98  			return
    99  		}
   100  		log.Debug(DRLManager.Report())
   101  	} else {
   102  		log.Warning("DRL not ready, skipping this notification")
   103  	}
   104  }