github.com/bitleak/lmstfy@v1.0.13/engine/redis/timer_test.go (about)

     1  package redis
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/sirupsen/logrus"
     9  
    10  	"github.com/bitleak/lmstfy/engine"
    11  )
    12  
    13  func TestTimer_Add(t *testing.T) {
    14  	timer, err := NewTimer("timer_set_1", R, time.Second)
    15  	if err != nil {
    16  		panic(fmt.Sprintf("Failed to new timer: %s", err))
    17  	}
    18  	job := engine.NewJob("ns-timer", "q1", []byte("hello msg 1"), 10, 0, 1, "")
    19  	if err = timer.Add(job.Namespace(), job.Queue(), job.ID(), 10, 1); err != nil {
    20  		t.Errorf("Failed to add job to timer: %s", err)
    21  	}
    22  }
    23  
    24  func TestTimer_Tick(t *testing.T) {
    25  	timer, err := NewTimer("timer_set_2", R, time.Second)
    26  	if err != nil {
    27  		panic(fmt.Sprintf("Failed to new timer: %s", err))
    28  	}
    29  	defer timer.Shutdown()
    30  	job := engine.NewJob("ns-timer", "q2", []byte("hello msg 2"), 5, 0, 1, "")
    31  	pool := NewPool(R)
    32  	pool.Add(job)
    33  	timer.Add(job.Namespace(), job.Queue(), job.ID(), 3, 1)
    34  	errChan := make(chan error, 1)
    35  	go func() {
    36  		var err error = nil
    37  		defer func() {
    38  			// BRPop could panic
    39  			if r := recover(); r != nil {
    40  				err = fmt.Errorf("recover with panic %v", r)
    41  			}
    42  			errChan <- err
    43  		}()
    44  		val, err := R.Conn.BRPop(dummyCtx, 5*time.Second, join(QueuePrefix, "ns-timer", "q2")).Result()
    45  		if err != nil || len(val) == 0 {
    46  			err = fmt.Errorf("Failed to pop the job from target queue")
    47  			return
    48  		}
    49  		tries, jobID, err := structUnpack(val[1])
    50  		if err != nil {
    51  			err = fmt.Errorf("Failed to decode the job pop from queue")
    52  			return
    53  		}
    54  		if tries != 1 || jobID != job.ID() {
    55  			err = fmt.Errorf("Job data mismatched")
    56  			return
    57  		}
    58  	}()
    59  	err = <-errChan
    60  	if err != nil {
    61  		t.Error(err)
    62  	}
    63  }
    64  
    65  func BenchmarkTimer(b *testing.B) {
    66  	// Disable logging temporarily
    67  	logger.SetLevel(logrus.ErrorLevel)
    68  	defer logger.SetLevel(logrus.DebugLevel)
    69  
    70  	t, err := NewTimer("timer_set_3", R, time.Second)
    71  	if err != nil {
    72  		panic(fmt.Sprintf("Failed to new timer: %s", err))
    73  	}
    74  	defer t.Shutdown()
    75  	b.Run("Add", benchmarkTimer_Add(t))
    76  
    77  	b.Run("Pop", benchmarkTimer_Pop(t))
    78  }
    79  
    80  func benchmarkTimer_Add(timer *Timer) func(b *testing.B) {
    81  	pool := NewPool(R)
    82  	return func(b *testing.B) {
    83  		for i := 0; i < b.N; i++ {
    84  			job := engine.NewJob("ns-timer", "q3", []byte("hello msg 1"), 100, 0, 1, "")
    85  			pool.Add(job)
    86  			timer.Add(job.Namespace(), job.Queue(), job.ID(), 1, 1)
    87  		}
    88  	}
    89  }
    90  
    91  func benchmarkTimer_Pop(timer *Timer) func(b *testing.B) {
    92  	return func(b *testing.B) {
    93  		key := join(QueuePrefix, "ns-timer", "q3")
    94  		b.StopTimer()
    95  		pool := NewPool(R)
    96  		for i := 0; i < b.N; i++ {
    97  			job := engine.NewJob("ns-timer", "q3", []byte("hello msg 1"), 100, 0, 1, "")
    98  			pool.Add(job)
    99  			timer.Add(job.Namespace(), job.Queue(), job.ID(), 1, 1)
   100  		}
   101  		b.StartTimer()
   102  		for i := 0; i < b.N; i++ {
   103  			R.Conn.BRPop(dummyCtx, 5*time.Second, key)
   104  		}
   105  	}
   106  }
   107  
   108  // How long did it take to fire 10000 due jobs
   109  func BenchmarkTimer_Pump(b *testing.B) {
   110  	// Disable logging temporarily
   111  	logger.SetLevel(logrus.ErrorLevel)
   112  	defer logger.SetLevel(logrus.DebugLevel)
   113  
   114  	b.StopTimer()
   115  
   116  	pool := NewPool(R)
   117  	timer, err := NewTimer("timer_set_4", R, time.Second)
   118  	if err != nil {
   119  		panic(fmt.Sprintf("Failed to new timer: %s", err))
   120  	}
   121  	timer.Shutdown()
   122  	for i := 0; i < 10000; i++ {
   123  		job := engine.NewJob("ns-timer", "q4", []byte("hello msg 1"), 100, 0, 1, "")
   124  		pool.Add(job)
   125  		timer.Add(job.Namespace(), job.Queue(), job.ID(), 1, 1)
   126  	}
   127  
   128  	b.StartTimer()
   129  	timer.pump(time.Now().Unix() + 1)
   130  }