It looks like the best approach is to do the svn operations in two steps: 1. Update the svn foundation/members.txt based on the request (active, emeritus, deceased) which is already in place. 2. Perform the moves in svn documents (emeritus-request-received>emeritus-request-rescinded, emeritus-request-received->emeritus) which is new code to be written.
These are two different svn repositories so they need to be in two svn commits anyway. And if the operations are retried on failure there is nothing to be done to coordinate the two operations. Meanwhile, I am sure that I do not know how to make the roster ruby/svn code retriable. I plan to start on figuring out how to do svn move from emeritus to emeritus-request-rescinded. Thanks, Craig > On May 26, 2020, at 10:37 PM, Sam Ruby <ru...@intertwingly.net> wrote: > > On Wed, May 27, 2020 at 12:38 AM Craig Russell <apache....@gmail.com> wrote: >> >> I'm not having any success understanding the memstat.json.rb code: >> # update members.txt >> _svn.update members_txt, message: message do |dir, text| >> >> Does this call the code in svn.rb? >> def self.update(path, msg, env, _, options={}) >> >> I guess I'm not so good at reading the ruby... > > The definition of _svn is here: > > https://github.com/apache/whimsy/blob/4e89c0e2a1069fbe7b6f4472722836c12a846e6c/www/roster/models/svn.rb#L29 > > It does indeed call the update method in lib/whimsy/asf/svn.rb. > > As an aside, the JavaScript module system, like Python, requires each > module to explicitly import what it needs, this makes it easier to > identify where the definition of a given method is. Enough so that > IDEs like VSCode allow you to control-click (or command-click on > MacOS) on a function call and it will take you to its definition. > >> I'm more used to the read/update/write/repeat/commit style of database >> access, where the memstat.json.rb would >> - read the members.txt >> - using the action (emeritus, active, deceased, request_emeritus, >> rescind_emeritus) edit the members.txt >> - move the file from emeritus-requests-received to emeritus (emeritus) >> - remove the file from emeritus-requests-received (rescind) >> - svn commit the changes > > That's indeed how it was done on the original whimsy_vm (effectively > whimsy_vm1). It routinely would get 'wedged' (that's the term you > used at the time) and I would have to ssh into that machine, run a > combination of svn reverts and svn cleanups until the directory was > clean again, then the operation could be attempted again. Perhaps you > might remember this happening. > > The second iteration creates a fresh checkout of the directory in > question, runs your block against that directory and commits the > results. Should the directory get 'wedged', the operation will fail, > but no matter what happens that temporary directory will be thrown > away, so the operation can be attempted again. This is the code you > are now looking at. > > The third iteration (present only in the Ruby board agenda tool at the > moment) takes this a step further and retries operations. Unlike the > secretary workbench and even to some extent the roster tool, the board > agenda tool is often used by multiple people concurrently, often with > changes to the same lines (most notably, the approval lines) on the > day before the board meeting. If a commit fails, a sleep for a random > time occurs and the operation is attempted again with a fresh checkout > and re-invoking the same block. I even have a test tool that > simulates 9 directors committing at once: > > https://github.com/apache/whimsy/blob/master/www/board/agenda/test/stresstest.rb > > The fourth iteration (currently being prototyped in > JavaScript/Node.js) is intended to incorporate the above retry logic > in production, but will also employ different strategies in > development and test. > > In the fullness of time, all of this should hopefully converge. > Meanwhile, build on the strategy that you feel most comfortable with, > and over time it will likely be rewritten as new strategies emerge. > >> Craig > > - Sam Ruby > >>> On May 26, 2020, at 6:09 PM, Sam Ruby <ru...@intertwingly.net> wrote: >>> >>> On Tue, May 26, 2020 at 8:44 PM Craig Russell <apache....@gmail.com> wrote: >>>> >>>> Sorry for not being clear. In the whimsy/lib there is a helper file svn.rb >>>> that has a number of functions including update(path, msg, env, _, >>>> options={}) that is used by roster memstat.json.rb and it contains the >>>> commit in the function. >>>> >>>> I did not see a move or remove function in svn.rb. Should I be looking >>>> somewhere else for examples of svn commands? Should I look at adding move >>>> and remove functions to svn.rb? >>> >>> Not currently. >>> >>> I'm convinced that the right way forward is for all svn access to be >>> done via what you are calling helpers. This not only makes the code >>> cleaner >>> >>> Ruby: File.read(File.join(ASF::SVN['foundation_board'], >>> 'board_agenda_06_17.txt') >>> JS: Board.read('board_agenda_06_17.txt') >>> >>> ... it also enables redirecting all commits to a local repository in >>> development, and mocking the repository in test. >>> >>> In any case, all of the svn operations should be updated to make use >>> of --password-from-stdin where available, which unfortunately won't be >>> until whimsy-vm is upgraded to Ubuntu 20.04. >>> >>>> Thanks, >>>> Craig >>> >>> - Sam Ruby >>> >>>>> On May 26, 2020, at 5:23 PM, Sam Ruby <ru...@intertwingly.net> wrote: >>>>> >>>>> On Tue, May 26, 2020 at 8:15 PM Craig Russell <apache....@gmail.com> >>>>> wrote: >>>>>> >>>>>> The cancel button now works (thanks, Sam). On to the server side. >>>>>> >>>>>> To implement active->emeritus we need to update members.txt and move the >>>>>> request file from emeritus-requests-received to emeritus. >>>>>> >>>>>> - Is there an svn function to move a file from one directory to another? >>>>> >>>>> http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.move.html >>>>> >>>>>> - Is there a way to have both things done in the same svn commit? >>>>> >>>>> If both the source and target have a common parent, do the svn commit >>>>> from that parent. >>>>> >>>>> When the secretary files board minutes, >>>>> 1) the minutes are moved to the website. Those source and target >>>>> don't share a common parent, so two commits are required. >>>>> 2) the agenda is moved to a subdirectory. The source and target share >>>>> a common parent, so one commit suffices. >>>>> >>>>>> To implement request_emeritus_status we need to create an email. Easy.. >>>>>> >>>>>> To implement rescind_emeritus_request we need to svn rm the file from >>>>>> emeritus-requests-received. >>>>>> >>>>>> - Is there an svn function to delete a file? >>>>> >>>>> http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.delete.html >>>>> >>>>>> Thanks, >>>>>> Craig >>>>> >>>>> - Sam Ruby >>>>> >>>>>>> On May 26, 2020, at 3:20 PM, Craig Russell <apache....@gmail.com> wrote: >>>>>>> >>>>>>> Here are the files. >>>>>>> <main.js.rb><memstat.js.rb> >>>>>>> And the console logs: >>>>>>> [Log] dblclick event.currentTarget: [object HTMLDivElement] (app.js, >>>>>>> line 3268) >>>>>>> [Log] dblclick event.currentTarget.dataset: [object DOMStringMap] >>>>>>> (app.js, line 3269) >>>>>>> [Log] dblclick event.currentTarget.dataset.edit: memstat (app.js, line >>>>>>> 3270) >>>>>>> [Log] canx called from Cancel button (app.js, line 4021) >>>>>>> [Log] event: [object MouseEvent] parent: [object HTMLButtonElement] >>>>>>> (app.js, line 4024) >>>>>>> [Log] parent: [object HTMLButtonElement] memstatElement: [object >>>>>>> HTMLDivElement] (app.js, line 4025) >>>>>>> [Log] preventing default (app.js, line 4026) >>>>>>> [Log] memstatElement.dataset: [object DOMStringMap] (app.js, line 4027) >>>>>>> [Log] memstatElement.dataset.edit: memstat (app.js, line 4028) >>>>>>> [Log] submit event: [object Object] (app.js, line 3291) >>>>>>> [Log] submit target: [object HTMLButtonElement] (app.js, line 3292) >>>>>>> [Log] submit parent: [object HTMLButtonElement] (app.js, line 3293) >>>>>>> [Log] submit parent.getAttribute(data_cancel): null (app.js, line 3294) >>>>>>> [Log] submit target.dataset_edit: undefined (app.js, line 3295) >>>>>>> [Log] submit target.dataset: [object DOMStringMap] (app.js, line 3296) >>>>>>> [Log] submit target.dataset.edit: undefined (app.js, line 3297) >>>>>>> [Log] submit memstatElement.dataset.edit: memstat (app.js, line 3298) >>>>>>> [Log] submit cancel_submit: null (app.js, line 3300) >>>>>>> >>>>>>>> On May 26, 2020, at 2:19 PM, Sam Ruby <ru...@intertwingly.net> wrote: >>>>>>>> >>>>>>>> On Tue, May 26, 2020 at 1:32 AM Craig Russell <apache....@gmail.com> >>>>>>>> wrote: >>>>>>>>> >>>>>>>>> But calling preventDefault on the event doesn't appear to do >>>>>>>>> anything. It still calls the POST behavior, and does not cause the >>>>>>>>> inline edit menu to disappear. And setting the edit function to nil >>>>>>>>> doesn't do anything either. >>>>>>>>> >>>>>>>>> Maybe there is something else that I need to do? >>>>>>>> >>>>>>>> I'll admit that I'm not clear on what you are trying to accomplish, >>>>>>>> but apparently the problem here is that there is another piece of code >>>>>>>> that attaches an event handler (and calls preventDefault): >>>>>>>> >>>>>>>> https://github.com/apache/whimsy/blob/d3246f107a35f4d989350f4c1ca64366c98ef423/www/roster/views/person/main.js.rb#L341 >>>>>>>> >>>>>>>> Perhaps it would be best to add an attribute to the button, and have >>>>>>>> the submit method remove the buttons and exit early: >>>>>>>> >>>>>>>> diff --git a/www/roster/views/person/main.js.rb >>>>>>>> b/www/roster/views/person/main.js.rb >>>>>>>> index 1b5ffdb8..f498489f 100644 >>>>>>>> --- a/www/roster/views/person/main.js.rb >>>>>>>> +++ b/www/roster/views/person/main.js.rb >>>>>>>> @@ -355,6 +355,12 @@ class Person < Vue >>>>>>>> form = jQuery(event.currentTarget).closest('form') >>>>>>>> target = event.target >>>>>>>> >>>>>>>> + # if button is a cancel button, don't submit and remove buttons >>>>>>>> + if target.getAttribute('data-cancel') >>>>>>>> + @edit = null >>>>>>>> + return >>>>>>>> + end >>>>>>>> + >>>>>>>> # serialize form >>>>>>>> formData = form.serializeArray(); >>>>>>>> >>>>>>>> diff --git a/www/roster/views/person/memstat.js.rb >>>>>>>> b/www/roster/views/person/memstat.js.rb >>>>>>>> index 39367c40..e8d3d318 100644 >>>>>>>> --- a/www/roster/views/person/memstat.js.rb >>>>>>>> +++ b/www/roster/views/person/memstat.js.rb >>>>>>>> @@ -35,6 +35,8 @@ class PersonMemberStatus < Vue >>>>>>>> _button.btn.btn_primary 'move to emeritus', >>>>>>>> name: 'action', value: 'emeritus' >>>>>>>> end >>>>>>>> + >>>>>>>> + _button.btn.btn_secondary 'cancel', data_cancel: true >>>>>>>> end >>>>>>>> end >>>>>>>> end >>>>>>>> >>>>>>>> - Sam Ruby >>>>>>> >>>>>>> Craig L Russell >>>>>>> c...@apache.org >>>>>>> >>>>>> >>>>>> Craig L Russell >>>>>> c...@apache.org >>>>>> >>>> >>>> Craig L Russell >>>> c...@apache.org >>>> >> >> Craig L Russell >> c...@apache.org >> Craig L Russell c...@apache.org