This is kind of a wild one. Turns out that the triggers I was using actually fire before the transaction is closed and I was primarily getting lucky that the job was present on the other side of the connection rather than having things built correctly. I've fixed this by removing the trigger entirely and instead manually triggering as part of the transaction. This makes the NOTIFY call happen as soon as the transaction closes, just at the cost of making my application be in charge of ensuring the NOTIFY gets called. Seems like a win. Part of doing this is porting the existing job creation code over to use Jet. It's something I want to do anyway, so it's a win all around.
96 lines
3.2 KiB
Go
96 lines
3.2 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/aarondl/opt/omit"
|
|
"github.com/aarondl/opt/omitnull"
|
|
"github.com/google/uuid"
|
|
"github.com/gorilla/mux"
|
|
"github.com/rs/zerolog/log"
|
|
"source.gleipnir.technology/Gleipnir/nidus-sync/db"
|
|
"source.gleipnir.technology/Gleipnir/nidus-sync/db/models"
|
|
"source.gleipnir.technology/Gleipnir/nidus-sync/platform"
|
|
"source.gleipnir.technology/Gleipnir/nidus-sync/platform/background"
|
|
"source.gleipnir.technology/Gleipnir/nidus-sync/platform/file"
|
|
)
|
|
|
|
func apiAudioPost(w http.ResponseWriter, r *http.Request, u platform.User) {
|
|
vars := mux.Vars(r)
|
|
id := vars["uuid"]
|
|
noteUUID, err := uuid.Parse(id)
|
|
if err != nil {
|
|
http.Error(w, "Failed to decode the uuid", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var payload NoteAudioPayload
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
http.Error(w, "Failed to read the payload", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if err := json.Unmarshal(body, &payload); err != nil {
|
|
//debugSaveRequest(body, err, "Audio note POST JSON decode error")
|
|
http.Error(w, "Failed to decode the payload", http.StatusBadRequest)
|
|
return
|
|
}
|
|
ctx := r.Context()
|
|
setter := models.NoteAudioSetter{
|
|
Created: omit.From(payload.Created),
|
|
CreatorID: omit.From(int32(u.ID)),
|
|
Deleted: omitnull.FromPtr(payload.Deleted),
|
|
DeletorID: omitnull.FromPtr(payload.DeletorID),
|
|
Duration: omit.From(payload.Duration),
|
|
OrganizationID: omit.From(u.Organization.ID),
|
|
Transcription: omitnull.FromPtr(payload.Transcription),
|
|
TranscriptionUserEdited: omit.From(payload.TranscriptionUserEdited),
|
|
Version: omit.From(payload.Version),
|
|
UUID: omit.From(noteUUID),
|
|
}
|
|
if err := platform.NoteAudioCreate(ctx, u, setter); err != nil {
|
|
if err := renderShim(w, r, errRender(err)); err != nil {
|
|
http.Error(w, fmt.Sprintf("render shim: %v", err), http.StatusInternalServerError)
|
|
}
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusAccepted)
|
|
}
|
|
|
|
func apiAudioContentPost(w http.ResponseWriter, r *http.Request, user platform.User) {
|
|
vars := mux.Vars(r)
|
|
u_str := vars["uuid"]
|
|
u, err := uuid.Parse(u_str)
|
|
if err != nil {
|
|
http.Error(w, "Failed to parse image UUID", http.StatusBadRequest)
|
|
return
|
|
}
|
|
err = file.FileContentWrite(r.Body, file.CollectionAudioRaw, u)
|
|
if err != nil {
|
|
log.Printf("Failed to write content file: %v", err)
|
|
http.Error(w, "failed to write content file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
ctx := r.Context()
|
|
a, err := models.NoteAudios.Query(
|
|
models.SelectWhere.NoteAudios.UUID.EQ(u),
|
|
models.SelectWhere.NoteAudios.OrganizationID.EQ(user.Organization.ID),
|
|
).One(ctx, db.PGInstance.BobDB)
|
|
if err != nil {
|
|
log.Printf("Failed to get note audio %s for org %d: %w", u_str, user.Organization.ID, err)
|
|
http.Error(w, "failed to update database", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
err = background.NewAudioTranscode(ctx, db.PGInstance.PGXPool, a.ID)
|
|
if err != nil {
|
|
log.Printf("Failed to transcode audio %s for org %d: %w", u_str, user.Organization.ID, err)
|
|
http.Error(w, "failed to transcode audio", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|