Skip to content

Commit 8ba71d0

Browse files
authored
Merge pull request #66 from owais/tiemouts
Added ability timeout when waiting for webpack to compile a bundle
2 parents ed0c1b7 + 6c297a0 commit 8ba71d0

File tree

10 files changed

+78
-8
lines changed

10 files changed

+78
-8
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
venv/
2+
13
# Byte-compiled / optimized / DLL files
24
__pycache__/
35
*.py[cod]

Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.PHONY: clean build deploy install publish
2+
3+
# Project settings
4+
PROJECT = webpack-loader
5+
6+
# Virtual environment settings
7+
ENV ?= venv
8+
9+
requirements = -r requirements-dev.txt
10+
11+
# List directories
12+
dist_dir = dist
13+
clean_dirs = $(PROJECT) $(ENV) $(tests_dir) $(shell [ -d $(tox_dir) ] && echo $(tox_dir) || :)
14+
15+
all: install build
16+
17+
clean:
18+
find webpack_loader/ -name '*.pyc' -delete
19+
rm -rf ./build ./*egg* ./.coverage
20+
21+
build: clean
22+
python setup.py sdist bdist_wheel --universal
23+
24+
install:
25+
[ ! -d $(ENV)/ ] && virtualenv $(ENV)/ || :
26+
$(ENV)/bin/pip install $(requirements)
27+
28+
publish: build
29+
$(ENV)/bin/twine upload dist/*

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ WEBPACK_LOADER = {
8383
'BUNDLE_DIR_NAME': 'bundles/', # must end with slash
8484
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
8585
'POLL_INTERVAL': 0.1,
86+
'TIMEOUT': None,
8687
'IGNORE': ['.+\.hot-update.js', '.+\.map']
8788
}
8889
}
@@ -147,12 +148,18 @@ and your webpack config is located at `/home/src/webpack.config.js`, then the va
147148
148149
#### POLL_INTERVAL
149150
150-
`POLL_INTERVAL` is the number of seconds webpack_loader should wait between polling the stats file. The stats file is polled every 200 miliseconds by default and any requests to are blocked while webpack compiles the bundles. You can reduce this if your bundles take shorter to compile.
151+
`POLL_INTERVAL` is the number of seconds webpack_loader should wait between polling the stats file. The stats file is polled every 100 miliseconds by default and any requests to are blocked while webpack compiles the bundles. You can reduce this if your bundles take shorter to compile.
151152
152153
**NOTE:** Stats file is not polled when in production (DEBUG=False).
153154
154155
<br>
155156
157+
#### TIMEOUT
158+
159+
`TIMEOUT` is the number of seconds webpack_loader should wait for webpack to finish compiling before raising an exception. `0`, `None` or leaving the value out of settings disables timeouts.
160+
161+
<br>
162+
156163
157164
## Usage
158165
<br>

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
twine==1.7.4

tests/app/tests/test_webpack.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
from unittest2 import skipIf
1313
from webpack_loader.exceptions import (
1414
WebpackError,
15-
WebpackLoaderBadStatsError
15+
WebpackLoaderBadStatsError,
16+
WebpackLoaderTimeoutError
1617
)
1718
from webpack_loader.utils import get_loader
1819

@@ -146,7 +147,6 @@ def test_jinja2(self):
146147
self.assertIn('<script type="text/javascript" src="/static/bundles/main.js" async charset="UTF-8"></script>', result.rendered_content)
147148

148149
def test_reporting_errors(self):
149-
#TODO:
150150
self.compile_bundles('webpack.config.error.js')
151151
try:
152152
get_loader(DEFAULT_CONFIG).get_bundle('main')
@@ -166,6 +166,17 @@ def test_missing_stats_file(self):
166166
).format(stats_file)
167167
self.assertIn(expected, str(e))
168168

169+
def test_timeouts(self):
170+
with self.settings(DEBUG=True):
171+
with open(
172+
settings.WEBPACK_LOADER[DEFAULT_CONFIG]['STATS_FILE'], 'w'
173+
) as stats_file:
174+
stats_file.write(json.dumps({'status': 'compiling'}))
175+
loader = get_loader(DEFAULT_CONFIG)
176+
loader.config['TIMEOUT'] = 0.1
177+
with self.assertRaises(WebpackLoaderTimeoutError):
178+
loader.get_bundle('main')
179+
169180
def test_bad_status_in_production(self):
170181
with open(
171182
settings.WEBPACK_LOADER[DEFAULT_CONFIG]['STATS_FILE'], 'w'

tests/db.sqlite3

33 KB
Binary file not shown.

webpack_loader/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
__author__ = 'Owais Lone'
2-
__version__ = '0.3.2'
2+
__version__ = '0.3.3'
33

44
default_app_config = 'webpack_loader.apps.WebpackLoaderConfig'

webpack_loader/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
'STATS_FILE': 'webpack-stats.json',
1414
# FIXME: Explore usage of fsnotify
1515
'POLL_INTERVAL': 0.1,
16+
'TIMEOUT': None,
1617
'IGNORE': ['.+\.hot-update.js', '.+\.map']
1718
}
1819
}

webpack_loader/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ class WebpackError(Exception):
77

88
class WebpackLoaderBadStatsError(Exception):
99
pass
10+
11+
12+
class WebpackLoaderTimeoutError(Exception):
13+
pass

webpack_loader/loader.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
from django.conf import settings
55
from django.contrib.staticfiles.storage import staticfiles_storage
66

7-
from .exceptions import WebpackError, WebpackLoaderBadStatsError
7+
from .exceptions import (
8+
WebpackError,
9+
WebpackLoaderBadStatsError,
10+
WebpackLoaderTimeoutError
11+
)
812
from .config import load_config
913

1014

@@ -53,13 +57,24 @@ def get_chunk_url(self, chunk):
5357
def get_bundle(self, bundle_name):
5458
assets = self.get_assets()
5559

60+
# poll when debugging and block request until bundle is compiled
61+
# or the build times out
5662
if settings.DEBUG:
57-
# poll when debugging and block request until bundle is compiled
58-
# TODO: support timeouts
59-
while assets['status'] == 'compiling':
63+
timeout = self.config['TIMEOUT'] or 0
64+
timed_out = False
65+
start = time.time()
66+
while assets['status'] == 'compiling' and not timed_out:
6067
time.sleep(self.config['POLL_INTERVAL'])
68+
if timeout and (time.time() - timeout > start):
69+
timed_out = True
6170
assets = self.get_assets()
6271

72+
if timed_out:
73+
raise WebpackLoaderTimeoutError(
74+
"Timed Out. Bundle `{0}` took more than {1} seconds "
75+
"to compile.".format(bundle_name, timeout)
76+
)
77+
6378
if assets.get('status') == 'done':
6479
chunks = assets['chunks'][bundle_name]
6580
return self.filter_chunks(chunks)

0 commit comments

Comments
 (0)