feat: resource store cache (#1742)

This commit is contained in:
boojack 2023-05-26 00:38:27 +08:00 committed by GitHub
parent b42e5c3213
commit de8014dfe8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 53 deletions

View file

@ -39,10 +39,9 @@ type MemoResponse struct {
Pinned bool `json:"pinned"`
// Related fields
CreatorName string `json:"creatorName"`
ResourceIDList []int
ResourceList []*Resource `json:"resourceList"`
RelationList []*MemoRelation `json:"relationList"`
CreatorName string `json:"creatorName"`
ResourceList []*Resource `json:"resourceList"`
RelationList []*MemoRelation `json:"relationList"`
}
type CreateMemoRequest struct {

View file

@ -119,7 +119,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo").SetInternal(err)
}
memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage))
memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
}
@ -235,7 +235,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find memo").SetInternal(err)
}
memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage))
memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
}
@ -298,7 +298,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
}
memoResponseList := []*api.MemoResponse{}
for _, memoMessage := range memoMessageList {
memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage))
memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
}
@ -334,7 +334,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusForbidden, "this memo is protected, missing user in session")
}
}
memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage))
memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
}
@ -373,7 +373,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
}
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to find memo by ID: %v", memoID)).SetInternal(err)
}
memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage))
memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
}
@ -461,7 +461,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
}
memoResponseList := []*api.MemoResponse{}
for _, memoMessage := range memoMessageList {
memoResponse, err := s.ComposeMemoResponse(ctx, convertMemoMessageToMemoResponse(memoMessage))
memoResponse, err := s.composeMemoMessageToMemoResponse(ctx, memoMessage)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err)
}
@ -584,27 +584,18 @@ func convertCreateMemoRequestToMemoMessage(memoCreate *api.CreateMemoRequest) *s
}
}
func convertMemoMessageToMemoResponse(memoMessage *store.MemoMessage) *api.MemoResponse {
relationList := []*api.MemoRelation{}
for _, relation := range memoMessage.RelationList {
relationList = append(relationList, convertMemoRelationMessageToMemoRelation(relation))
func (s *Server) composeMemoMessageToMemoResponse(ctx context.Context, memoMessage *store.MemoMessage) (*api.MemoResponse, error) {
memoResponse := &api.MemoResponse{
ID: memoMessage.ID,
RowStatus: api.RowStatus(memoMessage.RowStatus.String()),
CreatorID: memoMessage.CreatorID,
CreatedTs: memoMessage.CreatedTs,
UpdatedTs: memoMessage.UpdatedTs,
Content: memoMessage.Content,
Visibility: api.Visibility(memoMessage.Visibility.String()),
Pinned: memoMessage.Pinned,
}
return &api.MemoResponse{
ID: memoMessage.ID,
RowStatus: api.RowStatus(memoMessage.RowStatus.String()),
CreatorID: memoMessage.CreatorID,
CreatedTs: memoMessage.CreatedTs,
UpdatedTs: memoMessage.UpdatedTs,
Content: memoMessage.Content,
Visibility: api.Visibility(memoMessage.Visibility.String()),
Pinned: memoMessage.Pinned,
ResourceIDList: memoMessage.ResourceIDList,
RelationList: relationList,
}
}
func (s *Server) ComposeMemoResponse(ctx context.Context, memoResponse *api.MemoResponse) (*api.MemoResponse, error) {
user, err := s.Store.FindUser(ctx, &api.UserFind{
ID: &memoResponse.CreatorID,
})
@ -618,16 +609,23 @@ func (s *Server) ComposeMemoResponse(ctx context.Context, memoResponse *api.Memo
memoResponse.CreatorName = user.Username
}
memoResponse.ResourceList = []*api.Resource{}
for _, resourceID := range memoResponse.ResourceIDList {
relationList := []*api.MemoRelation{}
for _, relation := range memoMessage.RelationList {
relationList = append(relationList, convertMemoRelationMessageToMemoRelation(relation))
}
memoResponse.RelationList = relationList
resourceList := []*api.Resource{}
for _, resourceID := range memoMessage.ResourceIDList {
resource, err := s.Store.FindResource(ctx, &api.ResourceFind{
ID: &resourceID,
})
if err != nil {
return nil, err
}
memoResponse.ResourceList = append(memoResponse.ResourceList, resource)
resourceList = append(resourceList, resource)
}
memoResponse.ResourceList = resourceList
return memoResponse, nil
}

View file

@ -73,6 +73,28 @@ func (s *Store) CreateResource(ctx context.Context, create *api.ResourceCreate)
return resource, nil
}
func (s *Store) PatchResource(ctx context.Context, patch *api.ResourcePatch) (*api.Resource, error) {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return nil, FormatError(err)
}
defer tx.Rollback()
resourceRaw, err := patchResourceImpl(ctx, tx, patch)
if err != nil {
return nil, err
}
if err := tx.Commit(); err != nil {
return nil, FormatError(err)
}
s.resourceCache.Store(resourceRaw.ID, resourceRaw)
resource := resourceRaw.toResource()
return resource, nil
}
func (s *Store) FindResourceList(ctx context.Context, find *api.ResourceFind) ([]*api.Resource, error) {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
@ -87,6 +109,9 @@ func (s *Store) FindResourceList(ctx context.Context, find *api.ResourceFind) ([
resourceList := []*api.Resource{}
for _, raw := range resourceRawList {
if !find.GetBlob {
s.resourceCache.Store(raw.ID, raw)
}
resourceList = append(resourceList, raw.toResource())
}
@ -94,6 +119,11 @@ func (s *Store) FindResourceList(ctx context.Context, find *api.ResourceFind) ([
}
func (s *Store) FindResource(ctx context.Context, find *api.ResourceFind) (*api.Resource, error) {
if !find.GetBlob && find.ID != nil {
if raw, ok := s.resourceCache.Load(find.ID); ok {
return raw.(*resourceRaw).toResource(), nil
}
}
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return nil, FormatError(err)
@ -110,6 +140,9 @@ func (s *Store) FindResource(ctx context.Context, find *api.ResourceFind) (*api.
}
resourceRaw := list[0]
if !find.GetBlob {
s.resourceCache.Store(resourceRaw.ID, resourceRaw)
}
resource := resourceRaw.toResource()
return resource, nil
@ -132,31 +165,11 @@ func (s *Store) DeleteResource(ctx context.Context, delete *api.ResourceDelete)
if err := tx.Commit(); err != nil {
return FormatError(err)
}
s.resourceCache.Delete(delete.ID)
return nil
}
func (s *Store) PatchResource(ctx context.Context, patch *api.ResourcePatch) (*api.Resource, error) {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return nil, FormatError(err)
}
defer tx.Rollback()
resourceRaw, err := patchResourceImpl(ctx, tx, patch)
if err != nil {
return nil, err
}
if err := tx.Commit(); err != nil {
return nil, FormatError(err)
}
resource := resourceRaw.toResource()
return resource, nil
}
func createResourceImpl(ctx context.Context, tx *sql.Tx, create *api.ResourceCreate) (*resourceRaw, error) {
fields := []string{"filename", "blob", "external_link", "type", "size", "creator_id", "internal_path", "public_id"}
values := []any{create.Filename, create.Blob, create.ExternalLink, create.Type, create.Size, create.CreatorID, create.InternalPath, create.PublicID}

View file

@ -17,6 +17,7 @@ type Store struct {
userSettingCache sync.Map // map[string]*userSettingRaw
shortcutCache sync.Map // map[int]*shortcutRaw
idpCache sync.Map // map[int]*identityProviderMessage
resourceCache sync.Map // map[int]*resourceRaw
}
// New creates a new instance of Store.