mirror of
https://github.com/DeBrosOfficial/network.git
synced 2026-01-30 22:03:03 +00:00
132 lines
3.1 KiB
Go
132 lines
3.1 KiB
Go
package cache
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
olriclib "github.com/olric-data/olric"
|
|
)
|
|
|
|
// ScanHandler handles cache SCAN/LIST requests for listing keys in a distributed map.
|
|
// It expects a JSON body with "dmap" (distributed map name) and optionally "match" (regex pattern).
|
|
// Returns all keys in the map, or only keys matching the pattern if provided.
|
|
//
|
|
// Request body:
|
|
//
|
|
// {
|
|
// "dmap": "my-cache",
|
|
// "match": "user:*" // Optional: regex pattern to filter keys
|
|
// }
|
|
//
|
|
// Response:
|
|
//
|
|
// {
|
|
// "keys": ["user:123", "user:456"],
|
|
// "count": 2,
|
|
// "dmap": "my-cache"
|
|
// }
|
|
func (h *CacheHandlers) ScanHandler(w http.ResponseWriter, r *http.Request) {
|
|
if h.olricClient == nil {
|
|
writeError(w, http.StatusServiceUnavailable, "Olric cache client not initialized")
|
|
return
|
|
}
|
|
|
|
if r.Method != http.MethodPost {
|
|
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
|
return
|
|
}
|
|
|
|
var req ScanRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
writeError(w, http.StatusBadRequest, "invalid json body")
|
|
return
|
|
}
|
|
|
|
if strings.TrimSpace(req.DMap) == "" {
|
|
writeError(w, http.StatusBadRequest, "dmap is required")
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Namespace isolation: prefix dmap with namespace
|
|
namespace := getNamespaceFromContext(ctx)
|
|
if namespace == "" {
|
|
writeError(w, http.StatusUnauthorized, "namespace not found in context")
|
|
return
|
|
}
|
|
namespacedDMap := fmt.Sprintf("%s:%s", namespace, req.DMap)
|
|
|
|
olricCluster := h.olricClient.GetClient()
|
|
dm, err := olricCluster.NewDMap(namespacedDMap)
|
|
if err != nil {
|
|
writeError(w, http.StatusInternalServerError, fmt.Sprintf("failed to create DMap: %v", err))
|
|
return
|
|
}
|
|
|
|
var iterator olriclib.Iterator
|
|
if req.Match != "" {
|
|
iterator, err = dm.Scan(ctx, olriclib.Match(req.Match))
|
|
} else {
|
|
iterator, err = dm.Scan(ctx)
|
|
}
|
|
|
|
if err != nil {
|
|
writeError(w, http.StatusInternalServerError, fmt.Sprintf("failed to scan: %v", err))
|
|
return
|
|
}
|
|
defer iterator.Close()
|
|
|
|
var keys []string
|
|
for iterator.Next() {
|
|
keys = append(keys, iterator.Key())
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"keys": keys,
|
|
"count": len(keys),
|
|
"dmap": req.DMap,
|
|
})
|
|
}
|
|
|
|
// HealthHandler handles health check requests for the Olric cache service.
|
|
// Returns 200 OK if the cache is healthy, or 503 Service Unavailable if not.
|
|
//
|
|
// Response (success):
|
|
//
|
|
// {
|
|
// "status": "ok",
|
|
// "service": "olric"
|
|
// }
|
|
//
|
|
// Response (failure):
|
|
//
|
|
// {
|
|
// "error": "cache health check failed: ..."
|
|
// }
|
|
func (h *CacheHandlers) HealthHandler(w http.ResponseWriter, r *http.Request) {
|
|
if h.olricClient == nil {
|
|
writeError(w, http.StatusServiceUnavailable, "Olric cache client not initialized")
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
err := h.olricClient.Health(ctx)
|
|
if err != nil {
|
|
writeError(w, http.StatusServiceUnavailable, fmt.Sprintf("cache health check failed: %v", err))
|
|
return
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"status": "ok",
|
|
"service": "olric",
|
|
})
|
|
}
|