Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recreate passing tests and file-based and in-memory runQuery #370

Merged
merged 4 commits into from
Jun 6, 2019

Conversation

paweljakubas
Copy link
Contributor

Issue Number

#154

Overview

  • I have added unit tests that check file-backed sqlite db read/write/clean operation in a number of state changing scenerios
  • I have added property test that checks if we are in line with in-memory version when using random number of state changing operations in a row

Comments

This PR checks DB in two modes, ie., two places where db can reside : in-memory and in the file. And it seems they are not the same addressed within persistent, hence different runQuery'. Secondly, because these are two completely different mechanism (memory vs file system) they are differently serviced when detaching is realized. in-memory detaches gracefully, but file-based solution not so gracefully. It turn out that when we get rid of close we can easily end up with situation where we have too many file handles open and :

uncaught exception: SqliteException
SQLite3 returned ErrorCan'tOpen while attempting to perform open "backup/test.db".
(after 504 tests and 4 shrinks)

As evidenced above this happened after 503 successful test of prop_randomOpChunks (I commented close db and added not (null pairs) ==> withMaxSuccess 1000 $ monadicIO (pure inMemoryDB >>= prop)
When close db is on the test passes. This was the reason I decided to spend time investigating this issue. This also suggests to me that in file-based mode we need to use close and the test is needed, also runQuery' workaround. Otherwise, someone with small number of open handles in his/her computer will be subjected to this limitation, as anyone that uses our wallet-backend without interruption for long time (I am thinking here about exchanges).

# Ignore everything in this directory
*
# Except this file
!.gitignore
Copy link
Contributor Author

@paweljakubas paweljakubas Jun 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here will come mechanism of dealing with directories as in DB bench PR

enableForeignKeys conn = do
stmt <- Sqlite.prepare conn "PRAGMA foreign_keys = ON;"
_ <- Sqlite.step stmt
Sqlite.finalize stmt
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is needed for file-based. otherwise :

      1) Cardano.Wallet.DB.SqliteCorruption, Check db opening/closing, opening and closing of db works
           uncaught exception: SqliteException
           SQLite3 returned ErrorBusy while attempting to perform close: unable to close due to unfinalized statements or unfinished backups

pure (conn, backend)

createSqliteBackend1 :: Maybe FilePath -> LogFunc -> IO SqlBackend
createSqliteBackend1 fp logFunc = do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one can be married with createSqliteBackend

runQuery' = withMVar bigLock . const . runQuery conn
runQuery' cmd = case fp of
Nothing ->
withMVar bigLock $ const $ runQuery backend cmd
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in-memory - this cannot be used with file-based

Nothing ->
withMVar bigLock $ const $ runQuery backend cmd
_ ->
withMVar bigLock $ const $ runResourceT $ runNoLoggingT $ withSqlConn (createSqliteBackend1 fp)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file-based, this cannot be used with in-memory. Needs other pairs of eyes - at this moment do not see why


verify dbM dbF

close conn
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment this and add withMaxSuccess 1000 and will probably end up with :

     uncaught exception: SqliteException
       SQLite3 returned ErrorCan'tOpen while attempting to perform open "backup/test.db".
       (after 504 tests and 4 shrinks)

as I did in my laptop.

It suggests we need closing when using file-based Sqlite

handleChunks chunk = do
(conn, db) <- fileDBLayer
forM_ chunk (updateDB db)
close conn
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment this also to encounter open handle sooner

@paweljakubas
Copy link
Contributor Author

Please notice, all tests are green

Nothing )

withDB inMemoryDBLayer $
describe "random operation chunks property when writing to/reading from file" $ do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest the following:

    withDB inMemoryDBLayer $
        describe
            "random operation chunks property when writing to/reading from \
            \file" $ do

For compliance with https://github.com/input-output-hk/cardano-wallet/wiki/Coding-Standards#limit-line-length-to-80-characters

paweljakubas and others added 4 commits June 6, 2019 13:05
This solves the problem when dealing with the SQLite in-memory vs in-file database. By using 'SqlBackend' and calling close',
we do not break the abstraction boundary set by persistent and leave the connection management entirely up to persistent
@KtorZ KtorZ force-pushed the paweljakubas/154/file-based-and-inmemory branch from 4916de6 to b5aeff8 Compare June 6, 2019 11:06
Copy link
Member

@KtorZ KtorZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I've added a couple of changes + refactorings on top, so waiting for @paweljakubas to review back.

@paweljakubas
Copy link
Contributor Author

@KtorZ your commits looks very reasonable. I think we can merge it as it is

@KtorZ KtorZ merged commit 4d897a7 into master Jun 6, 2019
@KtorZ KtorZ deleted the paweljakubas/154/file-based-and-inmemory branch June 6, 2019 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants