3
3
* Copyright © Magento, Inc. All rights reserved.
4
4
* See COPYING.txt for license details.
5
5
*/
6
+
6
7
namespace Magento \Framework \Code ;
7
8
8
- use Magento \Framework \App \DeploymentConfig \Writer \PhpFormatter ;
9
9
use Magento \Framework \App \Filesystem \DirectoryList ;
10
- use Magento \Framework \Config \File \ConfigFilePool ;
10
+ use Magento \Framework \Exception \FileSystemException ;
11
+ use Magento \Framework \Exception \RuntimeException ;
11
12
use Magento \Framework \Filesystem \Directory \WriteFactory ;
12
13
use Magento \Framework \Filesystem \Directory \WriteInterface ;
14
+ use Magento \Framework \Lock \LockManagerInterface ;
13
15
14
16
/**
15
- * Regenerates generated code and DI configuration
17
+ * Clean generated code, DI configuration and cache folders
16
18
*/
17
19
class GeneratedFiles
18
20
{
19
21
/**
20
- * Separator literal to assemble timer identifier from timer names
22
+ * Regenerate flag file name
21
23
*/
22
24
const REGENERATE_FLAG = '/var/.regenerate ' ;
23
25
26
+ /**
27
+ * Regenerate lock file name
28
+ */
29
+ const REGENERATE_LOCK = self ::REGENERATE_FLAG . '.lock ' ;
30
+
31
+ /**
32
+ * Acquire regenerate lock timeout
33
+ */
34
+ const REGENERATE_LOCK_TIMEOUT = 5 ;
35
+
24
36
/**
25
37
* @var DirectoryList
26
38
*/
@@ -32,19 +44,39 @@ class GeneratedFiles
32
44
private $ write ;
33
45
34
46
/**
35
- * Constructor
47
+ * @var LockManagerInterface
48
+ */
49
+ private $ lockManager ;
50
+
51
+ /**
52
+ * GeneratedFiles constructor.
36
53
*
37
54
* @param DirectoryList $directoryList
38
55
* @param WriteFactory $writeFactory
56
+ * @param LockManagerInterface $lockManager
39
57
*/
40
- public function __construct (DirectoryList $ directoryList , WriteFactory $ writeFactory )
41
- {
58
+ public function __construct (
59
+ DirectoryList $ directoryList ,
60
+ WriteFactory $ writeFactory ,
61
+ LockManagerInterface $ lockManager
62
+ ) {
42
63
$ this ->directoryList = $ directoryList ;
43
64
$ this ->write = $ writeFactory ->create (BP );
65
+ $ this ->lockManager = $ lockManager ;
44
66
}
45
67
46
68
/**
47
- * Clean generated code and DI configuration
69
+ * Create flag for cleaning up generated content
70
+ *
71
+ * @return void
72
+ */
73
+ public function requestRegeneration ()
74
+ {
75
+ $ this ->write ->touch (self ::REGENERATE_FLAG );
76
+ }
77
+
78
+ /**
79
+ * Clean generated code, generated metadata and cache directories
48
80
*
49
81
* @return void
50
82
*
@@ -57,156 +89,75 @@ public function regenerate()
57
89
}
58
90
59
91
/**
60
- * Clean generated/ code, generated/ metadata and var/ cache
92
+ * Clean generated code, generated metadata and cache directories
61
93
*
62
94
* @return void
63
95
*/
64
96
public function cleanGeneratedFiles ()
65
97
{
66
- if ($ this ->write ->isExist (self ::REGENERATE_FLAG )) {
67
- $ enabledCacheTypes = [];
68
-
69
- //TODO: to be removed in scope of MAGETWO-53476
70
- $ deploymentConfig = $ this ->directoryList ->getPath (DirectoryList::CONFIG );
71
- $ configPool = new ConfigFilePool ();
72
- $ envPath = $ deploymentConfig . '/ ' . $ configPool ->getPath (ConfigFilePool::APP_ENV );
73
- if ($ this ->write ->isExist ($ this ->write ->getRelativePath ($ envPath ))) {
74
- $ enabledCacheTypes = $ this ->getEnabledCacheTypes ();
75
- $ this ->disableAllCacheTypes ();
76
- }
77
- //TODO: Till here
78
-
79
- $ cachePath = $ this ->write ->getRelativePath ($ this ->directoryList ->getPath (DirectoryList::CACHE ));
80
- $ generationPath = $ this ->write ->getRelativePath (
81
- $ this ->directoryList ->getPath (DirectoryList::GENERATED_CODE )
82
- );
83
- $ diPath = $ this ->write ->getRelativePath ($ this ->directoryList ->getPath (DirectoryList::GENERATED_METADATA ));
84
-
85
- // Clean generated/code dir
86
- if ($ this ->write ->isDirectory ($ generationPath )) {
87
- $ this ->write ->delete ($ generationPath );
88
- }
89
-
90
- // Clean generated/metadata
91
- if ($ this ->write ->isDirectory ($ diPath )) {
92
- $ this ->write ->delete ($ diPath );
98
+ if ($ this ->isCleanGeneratedFilesAllowed () && $ this ->acquireLock ()) {
99
+ try {
100
+ $ this ->write ->delete (self ::REGENERATE_FLAG );
101
+ $ this ->deleteFolder (DirectoryList::GENERATED_CODE );
102
+ $ this ->deleteFolder (DirectoryList::GENERATED_METADATA );
103
+ $ this ->deleteFolder (DirectoryList::CACHE );
104
+ } catch (FileSystemException $ exception ) {
105
+ // A filesystem error occurred, possible concurrency error while trying
106
+ // to delete a generated folder being used by another process.
107
+ // Request regeneration for the next and unlock
108
+ $ this ->requestRegeneration ();
109
+ } finally {
110
+ $ this ->lockManager ->unlock (self ::REGENERATE_LOCK );
93
111
}
94
-
95
- // Clean var/cache
96
- if ($ this ->write ->isDirectory ($ cachePath )) {
97
- $ this ->write ->delete ($ cachePath );
98
- }
99
- $ this ->write ->delete (self ::REGENERATE_FLAG );
100
- $ this ->enableCacheTypes ($ enabledCacheTypes );
101
112
}
102
113
}
103
114
104
115
/**
105
- * Create flag for cleaning up generated/code, generated/metadata and var/cache directories for subsequent
106
- * regeneration of this content
116
+ * Clean generated files is allowed if requested and not locked
107
117
*
108
- * @return void
118
+ * @return bool
109
119
*/
110
- public function requestRegeneration ()
120
+ private function isCleanGeneratedFilesAllowed (): bool
111
121
{
112
- $ this ->write ->touch (self ::REGENERATE_FLAG );
113
- }
114
-
115
- /**
116
- * Reads Cache configuration from env.php and returns indexed array containing all the enabled cache types.
117
- *
118
- * @return string[]
119
- */
120
- private function getEnabledCacheTypes ()
121
- {
122
- $ enabledCacheTypes = [];
123
- $ envPath = $ this ->getEnvPath ();
124
- if ($ this ->write ->isReadable ($ this ->write ->getRelativePath ($ envPath ))) {
125
- $ envData = include $ envPath ;
126
- if (isset ($ envData ['cache_types ' ])) {
127
- $ cacheStatus = $ envData ['cache_types ' ];
128
- $ enabledCacheTypes = array_filter ($ cacheStatus , function ($ value ) {
129
- return $ value ;
130
- });
131
- $ enabledCacheTypes = array_keys ($ enabledCacheTypes );
132
- }
122
+ try {
123
+ $ isAllowed = $ this ->write ->isExist (self ::REGENERATE_FLAG )
124
+ && !$ this ->lockManager ->isLocked (self ::REGENERATE_LOCK );
125
+ } catch (FileSystemException | RuntimeException $ e ) {
126
+ // Possible filesystem problem
127
+ $ isAllowed = false ;
133
128
}
134
- return $ enabledCacheTypes ;
135
- }
136
129
137
- /**
138
- * Returns path to env.php file
139
- *
140
- * @return string
141
- * @throws \Exception
142
- */
143
- private function getEnvPath ()
144
- {
145
- $ deploymentConfig = $ this ->directoryList ->getPath (DirectoryList::CONFIG );
146
- $ configPool = new ConfigFilePool ();
147
- $ envPath = $ deploymentConfig . '/ ' . $ configPool ->getPath (ConfigFilePool::APP_ENV );
148
- return $ envPath ;
130
+ return $ isAllowed ;
149
131
}
150
132
151
133
/**
152
- * Disables all cache types by updating env.php.
134
+ * Acquire lock for performing operations
153
135
*
154
- * @return void
136
+ * @return bool
155
137
*/
156
- private function disableAllCacheTypes ()
138
+ private function acquireLock (): bool
157
139
{
158
- $ envPath = $ this ->getEnvPath ();
159
- if ($ this ->write ->isWritable ($ this ->write ->getRelativePath ($ envPath ))) {
160
- $ envData = include $ envPath ;
161
-
162
- if (isset ($ envData ['cache_types ' ])) {
163
- $ cacheTypes = array_keys ($ envData ['cache_types ' ]);
164
-
165
- foreach ($ cacheTypes as $ cacheType ) {
166
- $ envData ['cache_types ' ][$ cacheType ] = 0 ;
167
- }
168
-
169
- $ formatter = new PhpFormatter ();
170
- $ contents = $ formatter ->format ($ envData );
171
-
172
- $ this ->write ->writeFile ($ this ->write ->getRelativePath ($ envPath ), $ contents );
173
- if (function_exists ('opcache_invalidate ' )) {
174
- opcache_invalidate (
175
- $ this ->write ->getAbsolutePath ($ envPath )
176
- );
177
- }
178
- }
140
+ try {
141
+ $ lockAcquired = $ this ->lockManager ->lock (self ::REGENERATE_LOCK , self ::REGENERATE_LOCK_TIMEOUT );
142
+ } catch (RuntimeException $ exception ) {
143
+ // Lock not acquired due to possible filesystem problem
144
+ $ lockAcquired = false ;
179
145
}
146
+
147
+ return $ lockAcquired ;
180
148
}
181
149
182
150
/**
183
- * Enables appropriate cache types in app/etc/env.php based on the passed in $cacheTypes array
184
- * TODO: to be removed in scope of MAGETWO-53476
151
+ * Delete folder by path
185
152
*
186
- * @param string[] $cacheTypes
153
+ * @param string $pathType
187
154
* @return void
188
155
*/
189
- private function enableCacheTypes ( $ cacheTypes )
156
+ private function deleteFolder ( string $ pathType ): void
190
157
{
191
- if (empty ($ cacheTypes )) {
192
- return ;
193
- }
194
- $ envPath = $ this ->getEnvPath ();
195
- if ($ this ->write ->isReadable ($ this ->write ->getRelativePath ($ envPath ))) {
196
- $ envData = include $ envPath ;
197
- foreach ($ cacheTypes as $ cacheType ) {
198
- if (isset ($ envData ['cache_types ' ][$ cacheType ])) {
199
- $ envData ['cache_types ' ][$ cacheType ] = 1 ;
200
- }
201
- }
202
-
203
- $ formatter = new PhpFormatter ();
204
- $ contents = $ formatter ->format ($ envData );
205
-
206
- $ this ->write ->writeFile ($ this ->write ->getRelativePath ($ envPath ), $ contents );
207
- if (function_exists ('opcache_invalidate ' )) {
208
- opcache_invalidate ($ this ->write ->getAbsolutePath ($ envPath ));
209
- }
158
+ $ relativePath = $ this ->write ->getRelativePath ($ this ->directoryList ->getPath ($ pathType ));
159
+ if ($ this ->write ->isDirectory ($ relativePath )) {
160
+ $ this ->write ->delete ($ relativePath );
210
161
}
211
162
}
212
163
}
0 commit comments