Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Feature response] Retry the unmounting operation 3 times #118

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

Merged
merged 1 commit into from
Apr 30, 2021
Merged

[Feature response] Retry the unmounting operation 3 times #118

merged 1 commit into from
Apr 30, 2021

Conversation

pzhlkj6612
Copy link
Contributor

Summary

Fixed #115

Related to #114 .

Added 3 attempts with backoff. I borrowed ideas from LinusU/node-appdmg#190 and modified the number of attempts from 5 to 3 per @aonez's suggestion (#115 (comment)).

Programming

set ±e

I think a temporary set +e may be required since you set set -e on the top of the script.
#115 (comment)

A temporary set +e is not required since the exit code of the statement executed in the {until... do} block is used to determine whether the {do... done} block will be executed. In other words, a non-zero exit code in the {until... do} block will not terminate the execution of a script with set -e . Therefore, we can safely test the exit code of hdiutil detach .

You can search "Exit immediately" in bash's manual page to see the official description.

how does it work

A small mock script:

#!/bin/bash


set -e

MAXIMUM_ATTEMPTS=3

attempts=0

until
    date --utc
    (( attempts++ ))
    bash -c "exit $1"
    exit_code=$?
    (( exit_code ==  0 )) && echo 'Nothing goes wrong' && break
    (( exit_code != 16 )) && echo 'Error (not 16)'     && exit $exit_code
do
    (( attempts == MAXIMUM_ATTEMPTS )) && echo 'Error 16' && exit 16
    echo 'wait';
    sleep $(( 1 * (2 ** attempts) ))
done

Execute it:

$ bash ./.sh 0
Fri Apr 30 08:19:22 UTC 2021
Nothing goes wrong
$ echo $?
0

$ bash ./.sh 1
Fri Apr 30 08:19:25 UTC 2021
Error (not 16)
$ echo $?
1

$ bash ./.sh 16
Fri Apr 30 08:19:27 UTC 2021
wait
Fri Apr 30 08:19:29 UTC 2021
wait
Fri Apr 30 08:19:33 UTC 2021
Error 16
$ echo $?
16

Test

I tested this on GitHub Actions. In the workflow, I tried to package Firefox like this:

...
      - uses: actions/checkout@v2
        with:
          ref: 'blahblah'

      - name: Catch the fox
        run: |
          bash ./create-dmg \
            ./dmg.dmg \
            /Applications/Firefox.app

And it works!

Log:

...
Fri, 30 Apr 2021 05:40:27 GMT | Unmounting disk image...
Fri, 30 Apr 2021 05:40:30 GMT | hdiutil: couldn't eject "disk2" - Resource busy
Fri, 30 Apr 2021 05:40:30 GMT | Wait a moment...
Fri, 30 Apr 2021 05:40:32 GMT | Unmounting disk image...
Fri, 30 Apr 2021 05:40:33 GMT | "disk2" ejected.
Fri, 30 Apr 2021 05:40:33 GMT | Compressing disk image...
...

Statistics:

EBUSY Failed Retried Total
Original code 6 6 / 400
New code 3 0 3 400

How to do statistics: By adding echo "::warning EBUSY" , I'm able to know how many instances retried the unmounting operation without checking the logs of all instances one by one.


Please review my code, thank you.

Add 3 attempts with backoff.
@aonez
Copy link
Member

aonez commented Apr 30, 2021

Overkill! Nice @pzhlkj6612!

This is a very needed fix, indeed.

@pzhlkj6612
Copy link
Contributor Author

FWIW:

Someone reported that detaching the volume on macOS Monterey (12.6) with Apple M1 Max may require 8-time attempts.

See LinusU/node-appdmg#214 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature request] Retry the unmounting operation?
2 participants