@@ -109,6 +109,42 @@ staterecovery-replay-from-block:
109109 docker compose -f docker/compose-tracing-v2-staterecovery-extension.yml down zkbesu-shomei-sr shomei-sr
110110 L1_ROLLUP_CONTRACT_ADDRESS=$(L1_ROLLUP_CONTRACT_ADDRESS ) STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER=$(STATERECOVERY_OVERRIDE_START_BLOCK_NUMBER ) docker compose -f docker/compose-tracing-v2-staterecovery-extension.yml up zkbesu-shomei-sr shomei-sr -d
111111
112+ # Retries TARGET up to RETRY_LIMIT times, aborting each attempt after
113+ # RETRY_TIMEOUT. Uses perl's alarm+exec instead of GNU coreutils `timeout`,
114+ # which isn't installed by default on macOS. Optionally runs
115+ # RETRY_CLEANUP_TARGET between failed attempts (e.g. to reset docker state).
116+ retry : RETRY_LIMIT:=5
117+ retry : RETRY_TIMEOUT:=10m
118+ retry : RETRY_BACKOFF:=10s
119+ retry :
120+ @if [ -z " $( TARGET) " ]; then \
121+ echo " Usage: make retry TARGET=<target> [RETRY_LIMIT=n] [RETRY_TIMEOUT=Xm] [RETRY_BACKOFF=Xs] [RETRY_CLEANUP_TARGET=<target>]" ; \
122+ exit 1; \
123+ fi ; \
124+ to_seconds () { \
125+ case " $$ 1" in \
126+ * h) echo $$(( $${1%h} * 3600 ) ) ;; \
127+ * m) echo $$(( $${1%m} * 60 ) ) ;; \
128+ * s) echo $$ {1%s} ;; \
129+ * ) echo " $$ 1" ;; \
130+ esac ; \
131+ }; \
132+ timeout_secs=$$(to_seconds $(RETRY_TIMEOUT ) ) ; \
133+ backoff_secs=$$(to_seconds $(RETRY_BACKOFF ) ) ; \
134+ attempt=1; \
135+ until perl -e ' alarm shift; exec @ARGV' $$ timeout_secs $( MAKE) $( TARGET) ; do \
136+ if [ $$ attempt -ge $( RETRY_LIMIT) ]; then \
137+ echo " Retry limit ($( RETRY_LIMIT) ) reached for target: $( TARGET) " ; \
138+ exit 1; \
139+ fi ; \
140+ echo " Attempt $$ attempt of '$( TARGET) ' failed. Retrying in $( RETRY_BACKOFF) ..." ; \
141+ if [ -n " $( RETRY_CLEANUP_TARGET) " ]; then \
142+ $(MAKE ) $(RETRY_CLEANUP_TARGET ) || true ; \
143+ fi ; \
144+ attempt=$$((attempt + 1 ) ); \
145+ sleep $$ backoff_secs; \
146+ done
147+
112148stop_pid :
113149 if [ -f $( PID_FILE) ]; then \
114150 kill ` cat $( PID_FILE) ` ; \
0 commit comments