github.com/wfusion/gofusion@v1.1.14/common/infra/asynq/asynqmon/queue_handlers.go (about)

     1  package asynqmon
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  
     7  	"github.com/gorilla/mux"
     8  
     9  	"github.com/wfusion/gofusion/common/infra/asynq"
    10  	"github.com/wfusion/gofusion/common/utils/serialize/json"
    11  )
    12  
    13  // ****************************************************************************
    14  // This file defines:
    15  //   - http.Handler(s) for queue related endpoints
    16  // ****************************************************************************
    17  
    18  func newListQueuesHandlerFunc(inspector *asynq.Inspector) http.HandlerFunc {
    19  	return func(w http.ResponseWriter, r *http.Request) {
    20  		qnames, err := inspector.Queues()
    21  		if err != nil {
    22  			http.Error(w, err.Error(), http.StatusInternalServerError)
    23  			return
    24  		}
    25  		snapshots := make([]*queueStateSnapshot, len(qnames))
    26  		for i, qname := range qnames {
    27  			qinfo, err := inspector.GetQueueInfo(qname)
    28  			if err != nil {
    29  				http.Error(w, err.Error(), http.StatusInternalServerError)
    30  				return
    31  			}
    32  			snapshots[i] = toQueueStateSnapshot(qinfo)
    33  		}
    34  		payload := map[string]any{"queues": snapshots}
    35  		json.NewEncoder(w).Encode(payload)
    36  	}
    37  }
    38  
    39  func newGetQueueHandlerFunc(inspector *asynq.Inspector) http.HandlerFunc {
    40  	return func(w http.ResponseWriter, r *http.Request) {
    41  		vars := mux.Vars(r)
    42  		qname := vars["qname"]
    43  
    44  		payload := make(map[string]any)
    45  		qinfo, err := inspector.GetQueueInfo(qname)
    46  		if err != nil {
    47  			// TODO: Check for queue not found error.
    48  			http.Error(w, err.Error(), http.StatusInternalServerError)
    49  			return
    50  		}
    51  		payload["current"] = toQueueStateSnapshot(qinfo)
    52  
    53  		// TODO: make this n a variable
    54  		data, err := inspector.History(qname, 10)
    55  		if err != nil {
    56  			http.Error(w, err.Error(), http.StatusInternalServerError)
    57  			return
    58  		}
    59  		var dailyStats []*dailyStats
    60  		for _, s := range data {
    61  			dailyStats = append(dailyStats, toDailyStats(s))
    62  		}
    63  		payload["history"] = dailyStats
    64  		json.NewEncoder(w).Encode(payload)
    65  	}
    66  }
    67  
    68  func newDeleteQueueHandlerFunc(inspector *asynq.Inspector) http.HandlerFunc {
    69  	return func(w http.ResponseWriter, r *http.Request) {
    70  		vars := mux.Vars(r)
    71  		qname := vars["qname"]
    72  		if err := inspector.DeleteQueue(qname, false); err != nil {
    73  			if errors.Is(err, asynq.ErrQueueNotFound) {
    74  				http.Error(w, err.Error(), http.StatusNotFound)
    75  				return
    76  			}
    77  			if errors.Is(err, asynq.ErrQueueNotEmpty) {
    78  				http.Error(w, err.Error(), http.StatusBadRequest)
    79  				return
    80  			}
    81  			http.Error(w, err.Error(), http.StatusInternalServerError)
    82  			return
    83  		}
    84  		w.WriteHeader(http.StatusNoContent)
    85  	}
    86  }
    87  
    88  func newPauseQueueHandlerFunc(inspector *asynq.Inspector) http.HandlerFunc {
    89  	return func(w http.ResponseWriter, r *http.Request) {
    90  		vars := mux.Vars(r)
    91  		qname := vars["qname"]
    92  		if err := inspector.PauseQueue(qname); err != nil {
    93  			http.Error(w, err.Error(), http.StatusInternalServerError)
    94  			return
    95  		}
    96  		w.WriteHeader(http.StatusNoContent)
    97  	}
    98  }
    99  
   100  func newResumeQueueHandlerFunc(inspector *asynq.Inspector) http.HandlerFunc {
   101  	return func(w http.ResponseWriter, r *http.Request) {
   102  		vars := mux.Vars(r)
   103  		qname := vars["qname"]
   104  		if err := inspector.UnpauseQueue(qname); err != nil {
   105  			http.Error(w, err.Error(), http.StatusInternalServerError)
   106  			return
   107  		}
   108  		w.WriteHeader(http.StatusNoContent)
   109  	}
   110  }
   111  
   112  type listQueueStatsResponse struct {
   113  	Stats map[string][]*dailyStats `json:"stats"`
   114  }
   115  
   116  func newListQueueStatsHandlerFunc(inspector *asynq.Inspector) http.HandlerFunc {
   117  	return func(w http.ResponseWriter, r *http.Request) {
   118  		qnames, err := inspector.Queues()
   119  		if err != nil {
   120  			http.Error(w, err.Error(), http.StatusInternalServerError)
   121  			return
   122  		}
   123  		resp := listQueueStatsResponse{Stats: make(map[string][]*dailyStats)}
   124  		const numdays = 90 // Get stats for the last 90 days.
   125  		for _, qname := range qnames {
   126  			stats, err := inspector.History(qname, numdays)
   127  			if err != nil {
   128  				http.Error(w, err.Error(), http.StatusInternalServerError)
   129  				return
   130  			}
   131  			resp.Stats[qname] = toDailyStatsList(stats)
   132  		}
   133  		if err := json.NewEncoder(w).Encode(resp); err != nil {
   134  			http.Error(w, err.Error(), http.StatusInternalServerError)
   135  			return
   136  		}
   137  	}
   138  }