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

Add script history #110

Merged
merged 1 commit into from
May 28, 2018
Merged

Conversation

takonomura
Copy link
Contributor

Add page to show script revisions.
definition_revisions

@@ -30,6 +30,7 @@ module PreventMultiStatus
has_many :job_suspend_schedules, dependent: :delete_all
has_many :job_definition_tags
has_many :tags, through: :job_definition_tags
has_many :revisions, -> { order(:id).reverse_order }, class_name: 'JobDefinitionRevision', dependent: :destroy
Copy link
Contributor

Choose a reason for hiding this comment

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

order(id: :desc) ?

Copy link
Member

@eisuke eisuke left a comment

Choose a reason for hiding this comment

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

I think we will want revision's permalink.
Are there plans to add it? (It is good even after this pull request.)

@@ -100,6 +101,12 @@ def create_instance(script: nil, launched_by:, token: nil )
job_instances.create!(script: script, log_message: message)
end

def record_revision(user: nil)
unless revisions.first.try(:script) == script
Kuroko2::JobDefinitionRevision.create(job_definition: self, script: script, user: user, changed_at: Time.now)
Copy link
Member

Choose a reason for hiding this comment

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

Kuroko2 needs to follow Rails time zone configuration. Please use Time.zone.now.

@@ -30,6 +30,7 @@ module PreventMultiStatus
has_many :job_suspend_schedules, dependent: :delete_all
has_many :job_definition_tags
has_many :tags, through: :job_definition_tags
has_many :revisions, -> { order(id: :desc) }, class_name: 'JobDefinitionRevision', dependent: :destroy
Copy link
Member

Choose a reason for hiding this comment

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

The JobDefinition model already has a version column. It may be confusing.
Possible options are as follows, I think.

  1. Remove JobDefinition's revision column.
  2. A JobDefinitionRevision has JobDefinition's revision column.

I think No.1 is better. What do you think?

@@ -16,6 +16,7 @@ def create_resource
user.stars.create(job_definition: definition) if user.google_account?
end

definition.record_revision
Copy link
Member

Choose a reason for hiding this comment

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

You may do it in JobDefinition's after_save.

@riseshia
Copy link
Contributor

riseshia commented Apr 9, 2018

reviewable pr? 🤔

@takonomura takonomura force-pushed the feature/script-history branch 3 times, most recently from 59a28c2 to 74841d6 Compare April 11, 2018 04:13
t.belongs_to :job_definition, foreign_key: true, null: false
t.text :script, null: false
t.belongs_to :user, foreign_key: true, null: true
t.datetime :changed_at, null: true
Copy link
Member

Choose a reason for hiding this comment

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

When does changed_at become null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Job definitions created before this changes have revision with null changed_at.

Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script)

Copy link
Contributor

Choose a reason for hiding this comment

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

Using updated_at as first changed_at seems reasonable to me, how do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using updated_at as first changed_at

Sorry, I don't understand. What do you mean?

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean

Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script)

to

Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script, changed_at: definition.updated_at)

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 changed in 3d7e119.

@@ -19,8 +19,6 @@ module PreventMultiStatus
PreventMultiStatus::ERROR => [Kuroko2::Token::FAILURE, Kuroko2::Token::CRITICAL],
}

self.locking_column = :version
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because version column has removed.

remove_column :job_definitions, :version

Copy link
Member

Choose a reason for hiding this comment

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

Why did you remove version column...?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Oops... I forgot that JobDefinition using optimistic locking. Please revert the commit 🙏

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 reverted the commit (4570e60)

@@ -50,6 +50,7 @@ def create

if @definition.save
current_user.stars.create(job_definition: @definition)
@definition.revisions.first.update(user: current_user)
Copy link
Member

Choose a reason for hiding this comment

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

This should be executed in the same transaction with @definition.save, I think.
Since revision requires user_id, running record_revision in after_save hook looks bad idea to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So should I revert 74841d6?
#110 (comment) @eisuke

Copy link
Member

Choose a reason for hiding this comment

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

This should be executed in the same transaction with @definition.save

I agree. But I'd like to avoid writing definition.record_revision in some controllers.
How about adding the #save_and_record_revision(attributes, edited_user: nil) method to JobDefinition model ?

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 changed in debd0db.

end

Kuroko2::JobDefinition.all.each do |definition|
Kuroko2::JobDefinitionRevision.create(job_definition: definition, script: definition.script)
Copy link
Member

Choose a reason for hiding this comment

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

This migration should not be run in rails db:rollback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I fixed in 8cc9ec4.

Copy link
Contributor

@riseshia riseshia left a comment

Choose a reason for hiding this comment

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

IMO) This resource will be created when JobDefinition's script changed, hence, JobDefinitionRevision may be not a good name.
How about just ScriptRevision?

@@ -100,6 +101,18 @@ def create_instance(script: nil, launched_by:, token: nil )
job_instances.create!(script: script, log_message: message)
end

def save_and_record_revision(edited_user: nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be executed in the same transaction with @definition.save, I think.
Since revision requires user_id, running record_revision in after_save hook looks bad idea to me.

I think @eagletmt means not only make it in one method, but execute in the real transaction, doesn't it?

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 fixed in 1066340.

@@ -0,0 +1,24 @@
- content_for :title, "##{@definition.id} #{@definition.name} « Job Definitions"
Copy link
Contributor

Choose a reason for hiding this comment

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

Definitions -> Definition Revisions?

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 fixed in bc22e19.


style= Diffy::CSS

- @revisions.each.with_index do |revision, i|
Copy link
Contributor

Choose a reason for hiding this comment

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

(maybe) Use each_cons(2) instead of this.
then html_diff doesn't need to allow nil case, is it right?

Copy link
Contributor Author

@takonomura takonomura Apr 25, 2018

Choose a reason for hiding this comment

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

If using each_cons(2), oldest revision will not displayed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, my comment was not proper. I should say why you want to show the oldest revision. (weak opinion)
It's better to use each_with_index(1) if you let it leave.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Showing the oldest revision explains initial script and who created the definition. I think this is helpful.

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 32) do
ActiveRecord::Schema.define(version: 33) do
Copy link
Contributor

Choose a reason for hiding this comment

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

👀 many tables seems to be deleted from schema, is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted tables were duplicated in schema.

Copy link
Contributor

Choose a reason for hiding this comment

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

🙈

t.belongs_to :job_definition, foreign_key: true, null: false
t.text :script, null: false
t.belongs_to :user, foreign_key: true, null: true
t.datetime :changed_at, null: true
Copy link
Contributor

Choose a reason for hiding this comment

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

Using updated_at as first changed_at seems reasonable to me, how do you think?

describe 'changes script' do
let(:script) { "noop:\nnoop:\n" }
it do
expect(response).to redirect_to(assigns(:definition))
Copy link
Contributor

Choose a reason for hiding this comment

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

indent

expect(assigns(:definition).revisions.size).to eq 2
expect(assigns(:definition).revisions.first.script).to eq script
expect(assigns(:definition).revisions.first.user).to eq controller.current_user

Copy link
Contributor

Choose a reason for hiding this comment

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

empty line 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you. I fixed in 12e87fa.

save
end

def update_and_record_revision(attributes, edited_user: nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this really worked in transaction? I don't think so 🤔
L105 seems to work well because job_definition is not saved when script revision assignment occurs.

irb(main):008:0> jd = JobDefinition.last
  JobDefinition Load (0.4ms)  SELECT  `job_definitions`.* FROM `job_definitions` ORDER BY `job_definitions`.`id` DESC LIMIT 1
=> #<JobDefinition id: 1, script: "a", created_at: "2018-04-27 06:42:42", updated_at: "2018-04-27 06:42:42">
irb(main):009:0> jd.assign_attributes(script: 'updated')
=> nil
irb(main):010:0> jd.script_revisions << ScriptRevision.new(script: 'updated')
   (0.2ms)  BEGIN
  ScriptRevision Create (6.1ms)  INSERT INTO `script_revisions` (`script`, `job_definition_id`, `created_at`, `updated_at`) VALUES ('updated', 1, '2018-04-27 06:47:05', '2018-04-27 06:47:05')
   (0.5ms)  COMMIT
  ScriptRevision Load (26.8ms)  SELECT  `script_revisions`.* FROM `script_revisions` WHERE `script_revisions`.`job_definition_id` = 1 LIMIT 11
=> #<ActiveRecord::Associations::CollectionProxy [#<ScriptRevision id: 1, script: "ab", job_definition_id: 1, created_at: "2018-04-27 06:42:42", updated_at: "2018-04-27 06:42:42">, #<ScriptRevision id: 2, script: "ccccc", job_definition_id: 1, created_at: "2018-04-27 06:43:15", updated_at: "2018-04-27 06:43:15">, #<ScriptRevision id: 3, script: "ccbsadf", job_definition_id: 1, created_at: "2018-04-27 06:43:34", updated_at: "2018-04-27 06:43:34">, #<ScriptRevision id: 4, script: "updated", job_definition_id: 1, created_at: "2018-04-27 06:47:05", updated_at: "2018-04-27 06:47:05">]>
irb(main):011:0> jd.save
   (0.2ms)  BEGIN
  JobDefinition Update (6.8ms)  UPDATE `job_definitions` SET `script` = 'updated', `updated_at` = '2018-04-27 06:47:18' WHERE `job_definitions`.`id` = 1
   (0.8ms)  COMMIT
=> true

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 fixed in dbb501e.

Copy link
Contributor

@riseshia riseshia left a comment

Choose a reason for hiding this comment

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

LGTM XD

riseshia pushed a commit to riseshia/kuroko2 that referenced this pull request May 17, 2018
There is the problem that tables has different type of primary key from
its installed:

- installed before 0.2.0: use unsigned int for primary key
- installed after 0.2.0: use signed int for primary key

This problem was maden by fa75b20.

This makes hard to keep consistency of code / infra.
For instance, we need to care about 2 types of primary when adding foreign key.
Actually, this problem already occured at cookpad#110

To solve the problem, this patch proposes to alter these primary key to
bigint, which is next default type of rails.
riseshia pushed a commit to riseshia/kuroko2 that referenced this pull request May 17, 2018
There is the problem that some tables has different type of primary key from
its installed:

- before 0.2.0: using unsigned int for primary key
- after 0.2.0: using signed int for primary key

This problem was made by fa75b20.

This makes hard to keep consistency of code / infra.
For instance, we need to care about 2 types of primary when adding foreign key.
Actually, this is already blocker of cookpad#110

To solve the problem, this patch proposes to alter these primary key to
bigint, which is next default type of rails.
riseshia pushed a commit to riseshia/kuroko2 that referenced this pull request May 18, 2018
There is the problem that some tables has different type of primary key from
its installed:

- before 0.2.0: using unsigned int for primary key
- after 0.2.0: using signed int for primary key

This problem was made by fa75b20.

This makes hard to keep consistency of code / infra.
For instance, we need to care about 2 types of primary when adding foreign key.
Actually, this is already blocker of cookpad#110

To solve the problem, this patch proposes to alter these primary key to
bigint, which is next default type of rails.
riseshia pushed a commit to riseshia/kuroko2 that referenced this pull request May 18, 2018
There is the problem that some tables has different type of primary key from
its installed:

- before 0.2.0: using unsigned int for primary key
- after 0.2.0: using signed int for primary key

This problem was made by fa75b20.

This makes hard to keep consistency of code / infra.
For instance, we need to care about 2 types of primary when adding foreign key.
Actually, this is already blocker of cookpad#110

To solve the problem, this patch proposes to alter these primary key to
bigint, which is next default type of rails.
riseshia pushed a commit to riseshia/kuroko2 that referenced this pull request May 18, 2018
There is the problem that some tables has different type of primary key from
its installed:

- before 0.2.0: using unsigned int for primary key
- after 0.2.0: using signed int for primary key

This problem was made by fa75b20.

This makes hard to keep consistency of code / infra.
For instance, we need to care about 2 types of primary when adding foreign key.
Actually, this is already blocker of cookpad#110

To solve the problem, this patch proposes to alter these primary key to
bigint, which is next default type of rails.
@riseshia
Copy link
Contributor

#117 is merged, could you update this pr? :)

@takonomura takonomura force-pushed the feature/script-history branch from dbb501e to c6130ed Compare May 23, 2018 00:50
@takonomura
Copy link
Contributor Author

Rebased

@riseshia
Copy link
Contributor

👍 Give me some more time to merge

@riseshia riseshia merged commit 43ecd97 into cookpad:master May 28, 2018
@riseshia
Copy link
Contributor

Thanks!!! XD

@takonomura takonomura deleted the feature/script-history branch May 30, 2018 00:44
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