Files
Assistant/cmd/cognitive-worker/admission.go
m 4c4a85aec6
CI / test (push) Successful in 24s
CI / test (pull_request) Successful in 22s
feat(cognitive): enforce durable admission leases
2026-08-22 14:33:53 +03:00

69 lines
2.2 KiB
Go

package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"git.cin.su/m/Assistant/contracts/capability"
)
type httpAdmissionClient struct {
baseURL string
client *http.Client
}
func newHTTPAdmissionClient(baseURL string, client *http.Client) *httpAdmissionClient {
return &httpAdmissionClient{baseURL: strings.TrimRight(baseURL, "/"), client: client}
}
func (c *httpAdmissionClient) Admit(ctx context.Context, leaseID string, request capability.AdmissionRequest) (capability.AdmissionDecision, capability.AdmissionLease, error) {
payload, err := json.Marshal(struct {
LeaseID string `json:"lease_id"`
Request capability.AdmissionRequest `json:"request"`
}{leaseID, request})
if err != nil {
return capability.AdmissionDecision{}, capability.AdmissionLease{}, err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+"/v1/internal/cognitive/admission", bytes.NewReader(payload))
if err != nil {
return capability.AdmissionDecision{}, capability.AdmissionLease{}, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.client.Do(req)
if err != nil {
return capability.AdmissionDecision{}, capability.AdmissionLease{}, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return capability.AdmissionDecision{}, capability.AdmissionLease{}, fmt.Errorf("admission status %d", resp.StatusCode)
}
var result struct {
Decision capability.AdmissionDecision `json:"decision"`
Lease capability.AdmissionLease `json:"lease"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return capability.AdmissionDecision{}, capability.AdmissionLease{}, err
}
return result.Decision, result.Lease, nil
}
func (c *httpAdmissionClient) Release(ctx context.Context, lease capability.AdmissionLease) error {
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+"/v1/internal/cognitive/admission/"+lease.ID+"/release", nil)
if err != nil {
return err
}
resp, err := c.client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
return fmt.Errorf("admission release status %d", resp.StatusCode)
}
return nil
}