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

exp/ingest/io: Refactor readers #2644

Merged
merged 5 commits into from
Jun 11, 2020

Conversation

bartekn
Copy link
Contributor

@bartekn bartekn commented Jun 1, 2020

PR Checklist

PR Structure

  • This PR has reasonably narrow scope (if not, break it down into smaller PRs).
  • This PR avoids mixing refactoring changes with feature changes (split into two PRs
    otherwise).
  • This PR's title starts with name of package that is most changed in the PR, ex.
    services/friendbot, or all or doc if the changes are broad or impact many
    packages.

Thoroughness

  • This PR adds tests for the most critical parts of the new functionality or fixes.
  • I've updated any docs (developer docs, .md
    files, etc... affected by this change). Take a look in the docs folder for a given service,
    like this one.

Release planning

  • I've updated the relevant CHANGELOG (here for Horizon) if
    needed with deprecations, added features, breaking changes, and DB schema changes.
  • I've decided if this PR requires a new major/minor version according to
    semver, or if it's mainly a patch change. The PR is targeted at the next
    release branch if it's not a patch change.
  • Add LedgerReader that gets LedgerCloseMeta from a provided ledger backend and is embedded by other readers.
  • Rename DBLedgerReader to LedgerTransactionReader because it works with any ledger backend. It now embeds LedgerReader.
  • LedgerChangeReader has been refactored and now embeds LedgerTransactionReader.
  • Updated GetChangesFromLedgerEntryChanges to be a public function.
  • Removed ctx.Context from readers because it's not idiomatic.
  • Removed unused interfaces and mocks.

Part of #2187.

@cla-bot cla-bot bot added the cla: yes label Jun 1, 2020
@bartekn bartekn changed the title exp/ingest/io: Refactor readers to not depend on DB reader exp/ingest/io: Refactor readers Jun 1, 2020
@bartekn bartekn marked this pull request as ready for review June 1, 2020 22:18
@bartekn bartekn requested a review from a team June 1, 2020 22:18
Copy link
Contributor

@abuiles abuiles left a comment

Choose a reason for hiding this comment

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

👍 minus some comments which are related to helping us make the code/functionality of the reader easier to understand.

return next, nil
}

switch r.state {
Copy link
Contributor

Choose a reason for hiding this comment

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

@bartekn would it make sense to put this whole section in its own function to better describe what this is doing? it seems like this function not only "reads" but also if there are no pending, loads tx data and fills pending.

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be helpful to document state and how we use it to move across the different kind of changes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a comment inside this method that explains what it's doing.

I can move parts to separate function but since this method actually fits the screen I think it's more readable that way. Let me know what you think.

@2opremio
Copy link
Contributor

2opremio commented Jun 2, 2020

How about LedgerBackendReader instead of LedgerTransactionReader ?


// LedgerReader reads ledger header from a given backend and ledger sequence.
// Use NewLedgerReader to create a new instance.
type LedgerReader struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

will there be another component that uses LedgerReader besides LedgerTransactionReader? If not, I don't see the point in having a separate type which is just a wrapper around backend.GetLedger(sequence)

@bartekn
Copy link
Contributor Author

bartekn commented Jun 2, 2020

How about LedgerBackendReader instead of LedgerTransactionReader?

Read() method actually reads transactions from a given ledger. I think the name matches the other reader: LedgerChangeReader that reads changes.

will there be another component that uses LedgerReader besides LedgerTransactionReader? If not, I don't see the point in having a separate type which is just a wrapper around backend.GetLedger(sequence)

Yes, I wanted to remove it completely but we need something like this in validateBucketList.

@@ -158,7 +158,7 @@ func (s *ProcessorRunner) validateBucketList(ledgerSequence uint32) error {
return errors.Wrap(err, "Error getting bucket list hash")
}

ledgerReader, err := io.NewDBLedgerReader(s.ctx, ledgerSequence, s.ledgerBackend)
ledgerReader, err := io.NewLedgerReader(s.ledgerBackend, ledgerSequence)
Copy link
Contributor

@tamirms tamirms Jun 3, 2020

Choose a reason for hiding this comment

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

I think it would be better to get rid of the LedgerReaderType and instead call ledgerBackend directly like:

	exists, ledgerCloseMeta, err := backend.GetLedger(sequence)
	if err != nil {
		return nil, errors.Wrap(err, "error getting ledger from the backend")
	}

	if !exists {
		return nil, ErrNotFound
	}
	ledgerBucketHashList := ledgerCloseMeta.LedgerHeader.Header. BucketListHash

it's true that the code which calls ledger backend will also be present in LedgerTransactionReader but I don't consider that code duplication. It's ok for backend.GetLedger to be called in multiple places

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that there are several advantages of keeping LedgerReader reader:

  • It's embedded in LedgerTransactionReader and LedgerChangeReader. For example, we call LedgerTransactionReader.GetHeader() in Horizon ingestion processors.
  • Although it now has just two methods that are rather simple I imagine we will add more helpers and complicated methods in the future. For example: GetCloseTime() that transforms ScpValue.CloseTime to time.Time or a verify function that checks if the ledger hash actually matches the contents or even validating bucket hash method (would accept history adapter).

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

regarding the first point, LedgerReader is only embedded in LedgerTransactionReader. LedgerChangeReader embeds LedgerTransactionReader. If the functions of LedgerReader become part ofLedgerTransactionReader then LedgerChangeReader will remain unaffected.

regarding the second point, I would rather those utility functions be defined on ledgerCloseMeta. The reason why I believe that's better is that it starts to get confusing when we have to distinguish between LedgerBackend, LedgerTransactionReader, LedgerChangeReader, and LedgerReader.

Copy link
Contributor

Choose a reason for hiding this comment

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

but if I'm the only one that finds it confusing then you can ignore my comment and leave it as is

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tamirms can you take a look?

regarding the second point, I would rather those utility functions be defined on ledgerCloseMeta. The reason why I believe that's better is that it starts to get confusing when we have to distinguish between LedgerBackend, LedgerTransactionReader, LedgerChangeReader, and LedgerReader.

Good point. Not doing this in this PR because this will likely be changed in #2633. I'm also not sure we should expose xdr.LedgerCloseMeta in the public release of ingest package because of #2128.

@bartekn bartekn merged commit f67623a into stellar:captive-core Jun 11, 2020
@bartekn bartekn deleted the refactor-exp-ingest-io branch June 11, 2020 17:55
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.

4 participants