@@ -57,7 +57,12 @@ pub fn blocking_install(version: &Version) -> Result<PathBuf, SvmError> {
5757 // same version of solc.
5858 let _lock = try_lock_file ( lock_path) ?;
5959
60- do_install ( version, & binbytes, artifact. to_string ( ) . as_str ( ) )
60+ do_install_and_retry (
61+ version,
62+ & binbytes,
63+ artifact. to_string ( ) . as_str ( ) ,
64+ & expected_checksum,
65+ )
6166}
6267
6368/// Installs the provided version of Solc in the machine.
@@ -98,7 +103,54 @@ pub async fn install(version: &Version) -> Result<PathBuf, SvmError> {
98103 // same version of solc.
99104 let _lock = try_lock_file ( lock_path) ?;
100105
101- do_install ( version, & binbytes, artifact. to_string ( ) . as_str ( ) )
106+ do_install_and_retry (
107+ version,
108+ & binbytes,
109+ artifact. to_string ( ) . as_str ( ) ,
110+ & expected_checksum,
111+ )
112+ }
113+
114+ /// Same as [`do_install`] but retries "text file busy" errors.
115+ fn do_install_and_retry (
116+ version : & Version ,
117+ binbytes : & [ u8 ] ,
118+ artifact : & str ,
119+ expected_checksum : & [ u8 ] ,
120+ ) -> Result < PathBuf , SvmError > {
121+ let mut retries = 0 ;
122+
123+ loop {
124+ return match do_install ( version, binbytes, artifact) {
125+ Ok ( path) => Ok ( path) ,
126+ Err ( err) => {
127+ // installation failed
128+ if retries > 2 {
129+ return Err ( err) ;
130+ }
131+ retries += 1 ;
132+ // check if this failed due to a text file busy, which indicates that a different process started using the target file
133+ if err. to_string ( ) . to_lowercase ( ) . contains ( "text file busy" ) {
134+ // busy solc can be in use for a while (e.g. if compiling a large project), so we check if the file exists and has the correct checksum
135+ let solc_path = version_binary ( & version. to_string ( ) ) ;
136+ if solc_path. exists ( ) {
137+ if let Ok ( content) = fs:: read ( & solc_path) {
138+ if ensure_checksum ( & content, version, expected_checksum) . is_ok ( ) {
139+ // checksum of the existing file matches the expected release checksum
140+ return Ok ( solc_path) ;
141+ }
142+ }
143+ }
144+
145+ // retry after some time
146+ std:: thread:: sleep ( Duration :: from_millis ( 250 ) ) ;
147+ continue ;
148+ }
149+
150+ Err ( err)
151+ }
152+ } ;
153+ }
102154}
103155
104156fn do_install ( version : & Version , binbytes : & [ u8 ] , _artifact : & str ) -> Result < PathBuf , SvmError > {
0 commit comments