mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
transactions as a list endpoint; added Transaction.CreatedAt
This commit is contained in:
parent
0dea018fb7
commit
1837811ce1
3 changed files with 53 additions and 2 deletions
|
|
@ -32,6 +32,7 @@ import (
|
|||
"reflect"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
|
@ -220,6 +221,7 @@ func (h *Handler) populateValidators() {
|
|||
h.validators["PostFieldAttrDiff"] = queryValidationSpecRequired()
|
||||
h.validators["GetNodes"] = queryValidationSpecRequired()
|
||||
h.validators["GetShardMax"] = queryValidationSpecRequired()
|
||||
h.validators["GetTransactionList"] = queryValidationSpecRequired()
|
||||
h.validators["GetTransactions"] = queryValidationSpecRequired()
|
||||
h.validators["GetTransaction"] = queryValidationSpecRequired()
|
||||
h.validators["PostTransaction"] = queryValidationSpecRequired()
|
||||
|
|
@ -362,6 +364,8 @@ func newRouter(handler *Handler) *mux.Router {
|
|||
router.HandleFunc("/schema", handler.handleGetSchema).Methods("GET").Name("GetSchema")
|
||||
router.HandleFunc("/schema", handler.handlePostSchema).Methods("POST").Name("PostSchema")
|
||||
router.HandleFunc("/status", handler.handleGetStatus).Methods("GET").Name("GetStatus")
|
||||
router.HandleFunc("/transaction", handler.handleGetTransactionList).Methods("GET").Name("GetTransactionList")
|
||||
router.HandleFunc("/transaction/", handler.handleGetTransactionList).Methods("GET").Name("GetTransactionList")
|
||||
router.HandleFunc("/transaction", handler.handlePostTransaction).Methods("POST").Name("PostTransaction")
|
||||
router.HandleFunc("/transaction/", handler.handlePostTransaction).Methods("POST").Name("PostTransaction")
|
||||
router.HandleFunc("/transaction/{id}", handler.handleGetTransaction).Methods("GET").Name("GetTransaction")
|
||||
|
|
@ -1241,6 +1245,41 @@ func (h *Handler) handleDeleteField(w http.ResponseWriter, r *http.Request) {
|
|||
resp.write(w, err)
|
||||
}
|
||||
|
||||
func (h *Handler) handleGetTransactionList(w http.ResponseWriter, r *http.Request) {
|
||||
if !validHeaderAcceptJSON(r.Header) {
|
||||
http.Error(w, "JSON only acceptable response", http.StatusNotAcceptable)
|
||||
return
|
||||
}
|
||||
trnsMap, err := h.api.Transactions(r.Context())
|
||||
if err != nil {
|
||||
switch errors.Cause(err) {
|
||||
case pilosa.ErrNodeNotCoordinator:
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
default:
|
||||
http.Error(w, "problem getting transactions: "+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Convert the map of transactions to a slice.
|
||||
trnsList := make([]*pilosa.Transaction, len(trnsMap))
|
||||
var i int
|
||||
for _, v := range trnsMap {
|
||||
trnsList[i] = v
|
||||
i++
|
||||
}
|
||||
|
||||
// Sort the slice by createdAt.
|
||||
sort.Slice(trnsList, func(i, j int) bool {
|
||||
return trnsList[i].CreatedAt.Before(trnsList[j].CreatedAt)
|
||||
})
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(trnsList); err != nil {
|
||||
h.logger.Printf("encoding GetTransactionList response: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) handleGetTransactions(w http.ResponseWriter, r *http.Request) {
|
||||
if !validHeaderAcceptJSON(r.Header) {
|
||||
http.Error(w, "JSON only acceptable response", http.StatusNotAcceptable)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ type Transaction struct {
|
|||
// Timeout is the minimum idle time for which this transaction should continue to exist.
|
||||
Timeout time.Duration `json:"timeout"`
|
||||
|
||||
// CreatedAt is the timestamp at which the transaction was created. This supports
|
||||
// the case of listing transactions in a useful order.
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
|
||||
// Deadline is calculated from Timeout. TODO reset deadline each time there is activity
|
||||
// on the transaction. (we can't do this until there is some method of associating a
|
||||
// request/call with a transaction)
|
||||
|
|
@ -130,12 +134,14 @@ func (tm *TransactionManager) Start(ctx context.Context, id string, timeout time
|
|||
active := !exclusive || (len(trnsMap) == 0)
|
||||
|
||||
// set deadline according to timeout
|
||||
deadline := time.Now().Add(timeout)
|
||||
createdAt := time.Now()
|
||||
deadline := createdAt.Add(timeout)
|
||||
trns := &Transaction{
|
||||
ID: id,
|
||||
Active: active,
|
||||
Exclusive: exclusive,
|
||||
Timeout: timeout,
|
||||
CreatedAt: createdAt,
|
||||
Deadline: deadline,
|
||||
}
|
||||
if err = tm.store.Put(trns); err != nil {
|
||||
|
|
@ -447,12 +453,14 @@ func (trns *Transaction) MarshalJSON() ([]byte, error) {
|
|||
Active bool `json:"active"`
|
||||
Exclusive bool `json:"exclusive"`
|
||||
Timeout string `json:"timeout"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
Deadline string `json:"deadline"`
|
||||
}{
|
||||
ID: trns.ID,
|
||||
Active: trns.Active,
|
||||
Exclusive: trns.Exclusive,
|
||||
Timeout: trns.Timeout.String(),
|
||||
CreatedAt: trns.CreatedAt.In(time.UTC).Format(time.RFC3339Nano),
|
||||
Deadline: trns.Deadline.In(time.UTC).Format(time.RFC3339Nano),
|
||||
})
|
||||
}
|
||||
|
|
@ -463,6 +471,7 @@ func (trns *Transaction) Copy() *Transaction {
|
|||
Active: trns.Active,
|
||||
Exclusive: trns.Exclusive,
|
||||
Timeout: trns.Timeout,
|
||||
CreatedAt: trns.CreatedAt,
|
||||
Deadline: trns.Deadline,
|
||||
Stats: trns.Stats,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ presumably cluster-wide.
|
|||
|
||||
The base transaction endpoints are `/transactions`, for listing or creating
|
||||
transactions, and `/transaction/[id]`, for listing, creating, finishing, or
|
||||
cancelling a transaction.
|
||||
cancelling a transaction. A GET to the `/transaction` endpoint (without an
|
||||
`[id]`) will return a list of all transactions ordered by their creation
|
||||
date: `createdAt`.
|
||||
|
||||
A POST to `/transaction` attempts to create a transaction, assigning it an
|
||||
arbitrary ID that is not the ID of any existing transaction. A `GET` from
|
||||
|
|
@ -214,6 +216,7 @@ This will return a JSON "transaction response" object.
|
|||
"active":true,
|
||||
"exclusive":false,
|
||||
"timeout":"1m0s",
|
||||
"createdAt":"2020-04-17T21:53:18.69359-05:00",
|
||||
"deadline":"2020-04-17T21:54:18.69359-05:00"
|
||||
},
|
||||
"error":"some message"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue