|
1 | 1 | import js.node.*;
|
2 | 2 | import js.node.http.*;
|
| 3 | +import js.Promise; |
3 | 4 |
|
4 | 5 | class Main {
|
5 | 6 | static function parseAuth(s:String)
|
@@ -45,20 +46,43 @@ class Main {
|
45 | 46 |
|
46 | 47 | static function update(remote, local, callback)
|
47 | 48 | {
|
48 |
| - trace("updating: fetching"); |
49 |
| - fetch(local, function (ferr, stdout, stderr) { |
50 |
| - if (ferr != null) { |
51 |
| - trace("updating: fetch failed, cloning"); |
52 |
| - clone(remote, local, function (cerr, stdout, stderr) { |
53 |
| - if (cerr != null) |
54 |
| - throw 'git clone exited with non-zero status: ${cerr.code}'; |
55 |
| - trace("updating: success"); |
56 |
| - callback(); |
| 49 | + if (!updatePromises.exists(local)) { |
| 50 | + updatePromises[local] = new Promise(function(resolve, reject) { |
| 51 | + trace("updating: fetching"); |
| 52 | + fetch(local, function (ferr, stdout, stderr) { |
| 53 | + if (ferr != null) { |
| 54 | + trace("updating: fetch failed, cloning"); |
| 55 | + clone(remote, local, function (cerr, stdout, stderr) { |
| 56 | + if (cerr != null) { |
| 57 | + resolve('git clone exited with non-zero status: ${cerr.code}'); |
| 58 | + } else { |
| 59 | + trace("updating: success"); |
| 60 | + resolve(null); |
| 61 | + } |
| 62 | + }); |
| 63 | + } else { |
| 64 | + trace("updating: success"); |
| 65 | + resolve(null); |
| 66 | + } |
57 | 67 | });
|
58 |
| - } else { |
59 |
| - trace("updating: success"); |
60 |
| - callback(); |
61 |
| - } |
| 68 | + }) |
| 69 | + .then(function(success) { |
| 70 | + updatePromises.remove(local); |
| 71 | + return Promise.resolve(success); |
| 72 | + }) |
| 73 | + .catchError(function(err) { |
| 74 | + updatePromises.remove(local); |
| 75 | + return Promise.reject(err); |
| 76 | + }); |
| 77 | + } else { |
| 78 | + trace("reusing existing promise"); |
| 79 | + } |
| 80 | + return updatePromises[local] |
| 81 | + .then(function(nothing:Dynamic) { |
| 82 | + trace("promise fulfilled"); |
| 83 | + callback(null); |
| 84 | + }, function(err:Dynamic) { |
| 85 | + callback(err); |
62 | 86 | });
|
63 | 87 | }
|
64 | 88 |
|
@@ -92,7 +116,14 @@ class Main {
|
92 | 116 | }
|
93 | 117 |
|
94 | 118 | if (params.isInfoRequest) {
|
95 |
| - update(remote, local, function () { |
| 119 | + update(remote, local, function (err) { |
| 120 | + if (err != null) { |
| 121 | + trace('ERROR: $err'); |
| 122 | + trace(haxe.CallStack.toString(haxe.CallStack.exceptionStack())); |
| 123 | + res.statusCode = 500; |
| 124 | + res.end(); |
| 125 | + return; |
| 126 | + } |
96 | 127 | res.statusCode = 200;
|
97 | 128 | res.setHeader("Content-Type", 'application/x-${params.service}-advertisement');
|
98 | 129 | res.setHeader("Cache-Control", "no-cache");
|
@@ -133,6 +164,7 @@ class Main {
|
133 | 164 | }
|
134 | 165 | }
|
135 | 166 |
|
| 167 | + static var updatePromises = new Map<String, Promise<Dynamic>>(); |
136 | 168 | static var cacheDir = "/tmp/var/cache/git/";
|
137 | 169 | static var listenPort = 8080;
|
138 | 170 | static var usage = "
|
|
0 commit comments