Skip to content

Commit

Permalink
feat: implement new simple transaction algorithm
Browse files Browse the repository at this point in the history
If `os.Mkdir("$VOLTPATH/trx/lock", 0755)` returns nil error,
It means it could start transaction successfully.
  • Loading branch information
tyru committed Apr 21, 2018
1 parent 5bd8d6a commit 0c59fa9
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 96 deletions.
25 changes: 13 additions & 12 deletions dsl/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package dsl

import (
"context"
"errors"

"github.com/pkg/errors"
"github.com/vim-volt/volt/dsl/op"
"github.com/vim-volt/volt/dsl/types"
)

Expand All @@ -21,17 +22,17 @@ const (

// Execute executes given expr with given ctx.
func Execute(ctx context.Context, expr *types.Expr) (val types.Value, rollback func(), err error) {
ctx = context.WithValue(ctx, CtxTrxIDKey, genNewTrxID())
if ctx.Value(CtxLockJSONKey) == nil {
return nil, func() {}, errors.New("no lock.json key in context")
}
if ctx.Value(CtxConfigKey) == nil {
return nil, func() {}, errors.New("no config.toml key in context")
for _, st := range []struct {
key CtxKeyType
name string
}{
{CtxLockJSONKey, "lock.json"},
{CtxConfigKey, "config.toml"},
{CtxTrxIDKey, "transaction ID"},
} {
if ctx.Value(st.key) == nil {
return nil, op.NoRollback, errors.Errorf("no %s key in context", st.name)
}
}
return expr.Eval(ctx)
}

func genNewTrxID() types.TrxID {
// TODO: Get unallocated transaction ID looking $VOLTPATH/trx/ directory
return types.TrxID(0)
}
6 changes: 0 additions & 6 deletions dsl/types/trxid.go

This file was deleted.

10 changes: 7 additions & 3 deletions migration/lockjson.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ Description
To suppress this, running this command simply reads and writes migrated structure to lock.json.`
}

func (*lockjsonMigrater) Migrate(lockJSON *lockjson.LockJSON, cfg *config.Config) error {
func (*lockjsonMigrater) Migrate(lockJSON *lockjson.LockJSON, cfg *config.Config) (result error) {
// Begin transaction
err := transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

// Write to lock.json
err = lockJSON.Write()
Expand Down
15 changes: 9 additions & 6 deletions migration/plugconf-config-func.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package migration

import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/pkg/errors"
"github.com/vim-volt/volt/config"
"github.com/vim-volt/volt/lockjson"
"github.com/vim-volt/volt/logger"
Expand Down Expand Up @@ -40,7 +40,7 @@ Description
All plugconf files are replaced with new contents.`
}

func (*plugconfConfigMigrater) Migrate(lockJSON *lockjson.LockJSON, cfg *config.Config) error {
func (*plugconfConfigMigrater) Migrate(lockJSON *lockjson.LockJSON, cfg *config.Config) (result error) {
results, parseErr := plugconf.ParseMultiPlugconf(lockJSON.Repos)
if parseErr.HasErrs() {
logger.Error("Please fix the following errors before migration:")
Expand Down Expand Up @@ -84,17 +84,20 @@ func (*plugconfConfigMigrater) Migrate(lockJSON *lockjson.LockJSON, cfg *config.
}

// Begin transaction
err := transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

// Build ~/.vim/pack/volt dir
err = builder.Build(false, lockJSON, cfg)
if err != nil {
return errors.New("could not build " + pathutil.VimVoltDir() + ": " + err.Error())
return errors.Wrap(err, "could not build "+pathutil.VimVoltDir())
}

return nil
}
6 changes: 3 additions & 3 deletions pathutil/pathutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ func ConfigTOML() string {
return filepath.Join(VoltPath(), "config.toml")
}

// TrxLock returns fullpath of "$HOME/volt/trx.lock".
func TrxLock() string {
return filepath.Join(VoltPath(), "trx.lock")
// TrxDir returns fullpath of "$HOME/volt/trx".
func TrxDir() string {
return filepath.Join(VoltPath(), "trx")
}

// TempDir returns fullpath of "$HOME/tmp".
Expand Down
10 changes: 7 additions & 3 deletions subcmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Description
return fs
}

func (cmd *buildCmd) Run(runctx *RunContext) *Error {
func (cmd *buildCmd) Run(runctx *RunContext) (cmdErr *Error) {
// Parse args
fs := cmd.FlagSet()
fs.Parse(runctx.Args)
Expand All @@ -62,12 +62,16 @@ func (cmd *buildCmd) Run(runctx *RunContext) *Error {
}

// Begin transaction
err := transaction.Create()
trx, err := transaction.Start()
if err != nil {
logger.Error()
return &Error{Code: 11, Msg: "Failed to begin transaction: " + err.Error()}
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
cmdErr = &Error{Code: 13, Msg: "Failed to end transaction: " + err.Error()}
}
}()

err = builder.Build(cmd.full, runctx.LockJSON, runctx.Config)
if err != nil {
Expand Down
10 changes: 7 additions & 3 deletions subcmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func (cmd *getCmd) getReposPathList(args []string, lockJSON *lockjson.LockJSON)
return reposPathList, nil
}

func (cmd *getCmd) doGet(reposPathList []pathutil.ReposPath, lockJSON *lockjson.LockJSON, cfg *config.Config) error {
func (cmd *getCmd) doGet(reposPathList []pathutil.ReposPath, lockJSON *lockjson.LockJSON, cfg *config.Config) (result error) {
// Find matching profile
profile, err := lockJSON.Profiles.FindByName(lockJSON.CurrentProfileName)
if err != nil {
Expand All @@ -190,11 +190,15 @@ func (cmd *getCmd) doGet(reposPathList []pathutil.ReposPath, lockJSON *lockjson.
}

// Begin transaction
err = transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

done := make(chan getParallelResult, len(reposPathList))
getCount := 0
Expand Down
50 changes: 35 additions & 15 deletions subcmd/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (cmd *profileCmd) parseArgs(args []string) ([]string, error) {
return fs.Args(), nil
}

func (cmd *profileCmd) doSet(runctx *RunContext) error {
func (cmd *profileCmd) doSet(runctx *RunContext) (result error) {
args := runctx.Args
lockJSON := runctx.LockJSON

Expand Down Expand Up @@ -190,11 +190,15 @@ func (cmd *profileCmd) doSet(runctx *RunContext) error {
}

// Begin transaction
err := transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

// Set profile name
lockJSON.CurrentProfileName = profileName
Expand Down Expand Up @@ -254,7 +258,7 @@ func (cmd *profileCmd) doList(runctx *RunContext) error {
`, runctx.LockJSON)
}

func (cmd *profileCmd) doNew(runctx *RunContext) error {
func (cmd *profileCmd) doNew(runctx *RunContext) (result error) {
args := runctx.Args
lockJSON := runctx.LockJSON

Expand All @@ -272,11 +276,15 @@ func (cmd *profileCmd) doNew(runctx *RunContext) error {
}

// Begin transaction
err = transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

// Add profile
lockJSON.Profiles = append(lockJSON.Profiles, lockjson.Profile{
Expand All @@ -295,7 +303,7 @@ func (cmd *profileCmd) doNew(runctx *RunContext) error {
return nil
}

func (cmd *profileCmd) doDestroy(runctx *RunContext) error {
func (cmd *profileCmd) doDestroy(runctx *RunContext) (result error) {
args := runctx.Args
lockJSON := runctx.LockJSON

Expand All @@ -306,11 +314,15 @@ func (cmd *profileCmd) doDestroy(runctx *RunContext) error {
}

// Begin transaction
err := transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

var merr *multierror.Error
for i := range args {
Expand Down Expand Up @@ -350,7 +362,7 @@ func (cmd *profileCmd) doDestroy(runctx *RunContext) error {
return merr.ErrorOrNil()
}

func (cmd *profileCmd) doRename(runctx *RunContext) error {
func (cmd *profileCmd) doRename(runctx *RunContext) (result error) {
args := runctx.Args
lockJSON := runctx.LockJSON

Expand All @@ -374,11 +386,15 @@ func (cmd *profileCmd) doRename(runctx *RunContext) error {
}

// Begin transaction
err := transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

// Rename profile names
lockJSON.Profiles[index].Name = newName
Expand Down Expand Up @@ -515,19 +531,23 @@ func (cmd *profileCmd) parseAddArgs(lockJSON *lockjson.LockJSON, subCmd string,
}

// Run modifyProfile and write modified structure to lock.json
func (*profileCmd) transactProfile(lockJSON *lockjson.LockJSON, profileName string, modifyProfile func(*lockjson.Profile)) (*lockjson.LockJSON, error) {
func (*profileCmd) transactProfile(lockJSON *lockjson.LockJSON, profileName string, modifyProfile func(*lockjson.Profile)) (resultLockJSON *lockjson.LockJSON, result error) {
// Return error if profiles[]/name does not match profileName
profile, err := lockJSON.Profiles.FindByName(profileName)
if err != nil {
return nil, err
}

// Begin transaction
err = transaction.Create()
trx, err := transaction.Start()
if err != nil {
return nil, err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

modifyProfile(profile)

Expand Down
10 changes: 7 additions & 3 deletions subcmd/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,17 @@ func (cmd *rmCmd) parseArgs(args []string) ([]pathutil.ReposPath, error) {
return reposPathList, nil
}

func (cmd *rmCmd) doRemove(reposPathList []pathutil.ReposPath, lockJSON *lockjson.LockJSON) error {
func (cmd *rmCmd) doRemove(reposPathList []pathutil.ReposPath, lockJSON *lockjson.LockJSON) (result error) {
// Begin transaction
err := transaction.Create()
trx, err := transaction.Start()
if err != nil {
return err
}
defer transaction.Remove()
defer func() {
if err := trx.Done(); err != nil {
result = err
}
}()

// Check if specified plugins are depended by some plugins
for _, reposPath := range reposPathList {
Expand Down
Loading

0 comments on commit 0c59fa9

Please sign in to comment.