Giter VIP home page Giter VIP logo

noid-rails's People

Contributors

atz avatar awead avatar bess avatar botimer avatar carolyncole avatar cbeer avatar cjcolvar avatar dgcliff avatar dlpierce avatar elrayle avatar escowles avatar jcoyne avatar jechols avatar jeremyf avatar jrgriffiniii avatar mejackreed avatar mjgiarlo avatar tpendragon avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

noid-rails's Issues

RENAME: Update references of hard-coded legacy master branch name to main branch name

Descriptive summary

This repository’s default branch has already been renamed using GitHub’s renaming tool. Links that reference the old branch name are automatically forwarded to the new default branch. But string references are not automatically updated.

Check this repository for hard-coded string references to the legacy “master” default branch and update them to the new default branch name “main.”

Important places to check include, but are not limited to:

  • READMEs
  • wikis
  • other documentation

NOTE: READMEs, wikis, and other documentation are important to update to avoid confusion and correct errors in long lasting documentation.

Less common places to check:

  • code
  • Issues/PRs

NOTE: String references to themaster branch in Issues, PRs, and code are uncommon. Also Issues and PRs are temporal in nature, making it less critical to update those occurrences.

Rationale

Git's default "master" branch derives from "master/slave" jargon which perpetuates systemic racist language and systems (see email Replacing "master" reference in git branch names). To uphold our Code of Conduct, we must move away from the term "master" in our technical language (as well as words like blacklist or whitelist).

Related work

DB minter design questions

The database-backed minter (db branch) is coming along well, but there are some design questions that need broader vetting.

LOCKING: Obviously we will use a DB transaction, but the transaction only helps for our connection. The point of the DB for horizontal scalability is that potentially many connections will be concurrent. What kind of locking do we want to use?

  1. optimistic -- downside: race condition, ActiveRecord::StaleObjectError
  2. pessimistic -- downside: deadlock
  3. db-specific (e.g. LOCK IN SHARE MODE) or other?

Pick your poison.

FAILSAFE: The point of locking is that one way or another only one connection/thread writes to the DB at a time. That means by design somebody loses (at write time for optimistic, at read time for pessimistic). The mint method is designed to loop forever until it gets a novel NOID, so presumably catching the failure there and retrying is OK, but at a certain scale, after a certain amount of failure, cycling forever in race/deadlock is counter-productive.

So, based on the lock you prefer, what tolerance for failure do we have here? Raise after 100 StaleObjectError or timeout after X to avoid deadlock?

RENAME: Add language to README about branch naming

Add the following branch renaming language to the README for this repository.

## Contributing 

If you're working on PR for this project, create a feature branch off of `main`. 

This repository follows the [Samvera Community Code of Conduct](https://samvera.atlassian.net/wiki/spaces/samvera/pages/405212316/Code+of+Conduct) and [language recommendations](https://github.com/samvera/maintenance/blob/master/templates/CONTRIBUTING.md#language).  Please ***do not*** create a branch called `master` for this repository or as part of your pull request; the branch will either need to be removed or renamed before it can be considered for inclusion in the code base and history of this repository.

Rationale

Git's default "master" branch derives from "master/slave" jargon which perpetuates systemic racist language and systems (see email Replacing "master" reference in git branch names). To uphold our Code of Conduct, we must move away from the term "master" in our technical language (as well as words like blacklist or whitelist).

Related work

Cannot override identifier_in_use lambda

Description

The identifier_in_use attribute can be changed by the identifier_in_use attr_writer, but it will not stay changed. Each time you call the reader it is changed back to the lambda that always returns false.

Expected

      def identifier_in_use
        @identifier_in_use ||= lambda do |_id|
          false
        end
      end

Actual

      def identifier_in_use
        @identifier_in_use = lambda do |_id|
          false
        end
      end

https://github.com/samvera/noid-rails/blob/master/lib/noid/rails/config.rb#L29

Discuss the right way to "bucket" assets

This is something I hadn't looked closely enough at before pushing the PR previously. If you override id generation, Fedora will properly be handed the desired path - for instance, be/19/d0/b2/2514nz446. If you do not override id generation and let Fedora do its UUID thing, Fedora chooses the path - for instance, 4a/48/49/6a/4a48496a-d56b-44a0-9836-e3381dfe13bd.

With UUIDs, the bucketing system is able to use the first 8 characters because they are never predictable. With NOIDs, there is a predictability, which is why I pushed up #3 to begin with.

The problem here can originate if you do not specify IDs prior to saving in Fedora for every single object you ever create. If there is any situation where an object is created in Fedora without both a predetermined PID and the overridden path translation code, things will be essentially unfindable by the app.

For most users this probably isn't an issue, but it's the sort of problem that could hit unexpectedly and won't make a lot of sense if it does.

I think the best long-term solution would be to let Fedora bucket by UUID and then have our pids be simply a piece of data associated with the object, rather than the pids being the definitive ID. I have no idea how to make this happen, as I (obviously) am not all that familiar with the Hydra stack, especially Fedora 4 / Hydra 9.

Barring that, it might be good to have the treeifier just return the id as-is unless it's a valid noid. Then anything not minted as a noid could just use the built-in fedora treeification. This is sort of weird and magicky, but it might be a good fix for the vast majority of use cases (e.g., creating a dummy asset in a test where the minting logic is deliberately not wanted).

RENAME: Add Circle CI step that fails if branch name is master

Descriptive summary

This repository’s default branch has already been renamed to main using GitHub’s renaming tool. In order to preserve automatic redirection of links that reference the old branch name master to the new default main branch, a branch with the old name should not be recreated.

CircleCI can be used to prevent the recreation of the old default branch name by preventing PRs with a branch named master from being merged by causing a test failure during continuous integration.

Rationale

Git's default "master" branch derives from "master/slave" jargon which perpetuates systemic racist language and systems (see email Replacing "master" reference in git branch names). To uphold our Code of Conduct, we must move away from the term "master" in our technical language (as well as words like blacklist or whitelist).

Expected behavior

If a PR is submitted with a branch named master, the continuous integration tests should fail.

Actual behavior

If a PR is submitted with a branch named master, the continuous integration tests will not fail because of the branch name.

Related work

Background on the renaming effort is available in the working group notes.

When URI has nested nodes the id is wrong

Currently:

uri = http://localhost:8983/fedora/rest/test/hh/63/vz/22/hh63vz22q/members"
p ActiveFedora::Base.uri_to_id(uri)
"members"

it should be

"hh63vz22q/members"

Wrong id for short ids

"http://localhost:8983/fedora/rest/test/te/st/5/test5/files"
(byebug) p ActiveFedora::Base.uri_to_id(uri)
"files"

I would expect test5/files instead

getting the wrong id for short ids.

translate_uri_to_id is dropping anchors.

ActiveFedora::Noid.config.translate_uri_to_id.call(RDF::URI('http://127.0.0.1:8986/rest/test/sf/26/85/66/sf2685667/list_source#g70294565559000')
=> "sf2685667/list_source"

But the default ActiveFedora one doesn't:

ActiveFedora::Core::FedoraUriTranslator.call(RDF::URI('http://127.0.0.1:8984/rest/dev/list_source#g70294565559000'))
=> "list_source#g70294565559000"

Discussion: Pick Default Minter

The default minter has been the file-based SynchronizedMinter. With the major version bump and availability of DB-backed minter, do we want to shift the default to that?

Add support for Ruby 2.7.z releases

Ruby 2.7.0 was released on 12/25/2019, and in accordance with the charter of the current phase of the Component Maintenance Working Group, the CircleCI configuration for this should be updated.

RENAME master branch to main

The Renaming Branch Working Group is in the process of renaming the default branch from master to main in Samvera and Samvera-Labs repos. This brings repositories into compliance with the Samvera Community Code of Conduct (https://samvera.atlassian.net/wiki/spaces/samvera/pages/405212316/Code+of+Conduct) and language recommendations (https://github.com/samvera/maintenance/blob/master/templates/CONTRIBUTING.md#language).

This issue will be complete when the master has been renamed to main.

Related issues will have a title beginning with RENAME.

DB minter locking logical problems

Pulled from my retrospective comment on #40.

I think it is problematic to have extracted locking to outside the transaction. Locking for update now happens in multiple places, including on every read. Previously only a transaction could block another transaction. Now a read can.

read and write! can now block each other: each calls instance which calls MinterState.lock.find_by, so they are not working on the same object, but each has a lock.

read and write! being public (and superficially documented) methods is sorta a problem. I mean, the Base class says read returns a Hash representing the minter state. Both it and the concrete class should be able to be more specific. (E.G., are the keys symbolic, string or mixed? what's this magic JSON marshalling?) Also, since it is public, a consumer might reasonably call read and be unaware that a locking operation is the result.

By my interpretation, read does not need SELECT ... FOR UPDATE for an instance it converts to a Hash, then throws away. Unlike before, no update ever comes for that object! The point of having the transaction was to put the read and the save! on the same object (as previously the case).

Add support for Rails 6.0.z releases

Rails version 6.0.0 was released on 08/16/2019, and in accordance with the charter of the current phase of the Component Maintenance Working Group, the CircleCI configuration for this should be updated.

Pin for a CurationConcerns issue

Migrating an object with a 7 digit id was yielding empty path segments in the members URI when CC was configured with the default (noid) id-uri translators. Reverting to AF basic fixed the problem.

Example: 1667751 -> /dev/16/67/75/1//1667751/members

Calling select on nil raises NoMethodError.

NoMethodError: private method `select' called for nil:NilClass

    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/db.rb:9 :in `read`

     7       class Db < Base
     8         def read
     9           filtered_hash = instance.as_json.select { |key| %w(template counters seq rand namespace).include?(key) }
    10           filtered_hash['counters'] = JSON.parse(filtered_hash['counters'], symbolize_names: true) if filtered_hash['counters']
    11           filtered_hash.symbolize_keys

    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/db.rb:38 :in `block in next_id`
    [GEM_ROOT]/gems/activerecord-5.0.1/lib/active_record/connection_adapters/abstract/database_statements.rb:232 :in `block in transaction`
    [GEM_ROOT]/gems/activerecord-5.0.1/lib/active_record/connection_adapters/abstract/transaction.rb:189 :in `within_new_transaction`
    [GEM_ROOT]/gems/activerecord-5.0.1/lib/active_record/connection_adapters/abstract/database_statements.rb:232 :in `transaction`
    [GEM_ROOT]/gems/activerecord-5.0.1/lib/active_record/transactions.rb:211 :in `transaction`

    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/db.rb:37 :in `next_id`

    35         def next_id
    36           id = nil
    37           MinterState.transaction do
    38             state = read
    39             minter = ::Noid::Minter.new(state)

    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/base.rb:25 :in `block (2 levels) in mint`
    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/base.rb:24 :in `loop`
    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/base.rb:24 :in `block in mint`
    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/base.rb:23 :in `synchronize`
    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/minter/base.rb:23 :in `mint`
    [GEM_ROOT]/gems/active_fedora-noid-2.0.0/lib/active_fedora/noid/service.rb:15 :in `mint`
    [GEM_ROOT]/bundler/gems/hyrax-d247dd973fb6/app/services/hyrax/noid.rb:10 :in `assign_id`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/persistence.rb:206 :in `assign_rdf_subject`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/persistence.rb:165 :in `_create_record`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/indexing.rb:63 :in `_create_record`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/callbacks.rb:240 :in `block in _create_record`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:126 :in `call`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:506 :in `block (2 levels) in compile`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:455 :in `call`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:101 :in `__run_callbacks__`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:750 :in `_run_create_callbacks`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/callbacks.rb:240 :in `_create_record`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/persistence.rb:159 :in `create_or_update`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/callbacks.rb:236 :in `block in create_or_update`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:126 :in `call`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:506 :in `block (2 levels) in compile`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:455 :in `call`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:101 :in `__run_callbacks__`
    [GEM_ROOT]/gems/activesupport-5.0.1/lib/active_support/callbacks.rb:750 :in `_run_save_callbacks`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/callbacks.rb:236 :in `create_or_update`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/persistence.rb:29 :in `save`
    [GEM_ROOT]/gems/active-fedora-11.0.1/lib/active_fedora/validations.rb:50 :in `save`
    [GEM_ROOT]/bundler/gems/hyrax-d247dd973fb6/app/services/hyrax/admin_set_create_service.rb:19 :in `create`

    17       admin_set.edit_groups = ['admin']
    18       admin_set.creator = [creating_user.user_key]
    19       admin_set.save.tap do |result|
    20         create_permission_template if result
    21       end

Generator fails with Active Fedora 10.1.0

Running rails generate active_fedora:noid:install results in the following error:

[WARNING] Could not load generator "generators/active_fedora/noid/install_generator". Error: undefined method `expand_path' for ActiveFedora::File:Class.
/Users/dixonj16/.rvm/gems/ruby-2.3.0/gems/active_fedora-noid-2.0.0.beta1/lib/generators/active_fedora/noid/install_generator.rb:4:in `<class:InstallGenerator>'
/Users/dixonj16/.rvm/gems/ruby-2.3.0/gems/active_fedora-noid-2.0.0.beta1/lib/generators/active_fedora/noid/install_generator.rb:3:in `<module:Noid>'

This can be reproduced by creating a new rails app and adding the following gems.

gem 'active_fedora-noid', '2.0.0.beta1'
gem 'active-fedora', '10.1.0'

Running generator raises an error.

$ rails g active_fedora:noid:install
        info  Installing ActiveFedora::Noid
        rake  active_fedora_noid_engine:install:migrations
rake aborted!
Don't know how to build task 'active_fedora_noid_engine:install:migrations' (see --tasks)

(See full trace by running task with --trace)
        rake  db:migrate
    generate  active_fedora:noid:seed
        info  Initializing database table for namespace:template of 'default:.reeddeeddk'
/Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/active_fedora-noid-2.0.0.beta3/lib/generators/active_fedora/noid/seed_generator.rb:22:in `seed_row': uninitialized constant ActiveFedora::Noid::SeedGenerator::MinterState (NameError)
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `block in invoke_all'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `each'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `map'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `invoke_all'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/group.rb:232:in `dispatch'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/generators.rb:180:in `invoke'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/generate.rb:13:in `<top (required)>'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:138:in `require_command!'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:145:in `generate_or_destroy'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:60:in `generate'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
    from /Users/jcoyne/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.0.1/lib/rails/commands.rb:18:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

Should default_solr_param be overrideable?

class LocalNames
  include Blacklight::SearchHelper
  include Blacklight::Configurable

  copy_blacklight_config_from CatalogController

  blacklight_config do |conf|
    # conf.search_builder_class = LocalNameSearchBuilder
    config.default_solr_params = {
      'qf' => 'foaf_name_tesim',
    }
  end

  def initialize
    puts blacklight_config.default_solr_params
  end
end
LocalNames.new

This prints out the CatalogController defaults, not the defaults I set in this class. Is that right?

new DB-backed minter

Reliance on filesystem for statefile prevents horizontal scaling of the application (as we need in HyBox). Reliance on single path in filesystem also blocks multitenancy. The solution for either of these is to use a db-backed "statefile".

Design questions

Should this be a separate class here akin to SynchronizedMinter? a fork of this project? a totally independent gem?

For performance, ideally the minter is a stored procedure in the db-layer, to minimize the exclusive lock duration. Potentially a second implementation might be required in sqlite3 for development (still useless for the production cases mentioned above). It might need separate code for mysql and postgres. But introduction of specific db-adapter dependencies in AF:noid seems undesirable, or at least a marked shift in the profile of the gem.

If created at a rails engine level (Sufia, CurationConcerns, etc.), the dependency profile there doesn't change (as much), but the reusability of the minter is limited.

I am leaning towards a separate gem, possibly a separate gem per DB adapter. I'd welcome some feedback from folks w/ more experience around current noid generation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.