Skip to content

Commit db32711

Browse files
Introduce Windows® Operating System support for the matlab-proxy package.
1 parent 45276dc commit db32711

25 files changed

+880
-167
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
__pycache__/
44
build/
55
dist/
6-
.venv/
6+
.venv*/
77
.vscode/
88
htmlcov/
99
.coverage

README.md

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# MATLAB Proxy
2-
32
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/mathworks/matlab-proxy/Testing%20MATLAB%20Proxy?logo=github)](https://github.com/mathworks/matlab-proxy/actions)   [![PyPI badge](https://img.shields.io/pypi/v/matlab-proxy.svg?logo=pypi)](https://pypi.python.org/pypi/matlab-proxy)   [![codecov](https://codecov.io/gh/mathworks/matlab-proxy/branch/main/graph/badge.svg?token=ZW3SESKCSS)](https://codecov.io/gh/mathworks/matlab-proxy)   [![Downloads](https://static.pepy.tech/personalized-badge/matlab-proxy?period=month&units=international_system&left_color=grey&right_color=blue&left_text=PyPI%20downloads/month)](https://pepy.tech/project/matlab-proxy)
43

54
Copyright (c) 2020-2022 The MathWorks, Inc. All rights reserved.
@@ -26,16 +25,18 @@ The MATLAB Proxy is under active development. For support or to report issues, s
2625
- [Feedback](#feedback)
2726

2827
## Requirements
29-
* Linux® operating system
28+
* Linux® or a Windows® Operating System
3029

3130
* MATLAB® R2020b or later is installed and on the system PATH.
3231
```bash
3332
# Confirm MATLAB is on the PATH
3433
which matlab
35-
```
34+
```
3635
* The dependencies required to run MATLAB.
3736
Refer to the Dockerfiles in the [matlab-deps](https://github.com/mathworks-ref-arch/container-images/tree/master/matlab-deps) repository for the desired version of MATLAB.
38-
* X Virtual Frame Buffer (Xvfb)
37+
38+
* X Virtual Frame Buffer (Xvfb) : (only for Linux® based systems)
39+
3940
Install it on your linux machine using:
4041
```bash
4142
# On a Debian/Ubuntu based system:
@@ -130,6 +131,28 @@ The following options are available in the status panel (some options are only a
130131
* For upgrading **matlab-proxy** in an existing Docker image, see this [Dockerfile.upgrade.matlab-proxy](./examples/Dockerfile.upgrade.matlab-proxy) and its [README](./examples/README.md#upgrading-matlab-proxy-package-in-a-docker-image).*
131132
* For usage in a Jupyter environment, see [jupyter-matlab-proxy](https://github.com/mathworks/jupyter-matlab-proxy).
132133

134+
## Platform Support
135+
136+
### Linux
137+
This package is fully supported for the Linux Operating System.
138+
139+
### Windows
140+
141+
Windows® Operating System support was introduced in package version `v0.4.0`. If you encounter any errors, see the [Feedback](#feedback) section to report them.
142+
143+
Install the version >=0.4.0 to use the package on Windows.
144+
```bash
145+
# To upgrade an existing installation of matlab-proxy package:
146+
$ pip install --upgrade matlab-proxy>=0.4.0
147+
148+
# Or to make a new installation of the latest version:
149+
$ pip install matlab-proxy
150+
```
151+
152+
### MacOS
153+
154+
This package is not supported for the Apple® Mac Operating System.
155+
133156
## Limitations
134157
This package supports the same subset of MATLAB features and commands as MATLAB® Online, except there is no support for Simulink® Online.
135158
[Click here for a full list of Specifications and Limitations for MATLAB Online](https://www.mathworks.com/products/matlab-online/limitations.html).

conftest.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright 2020-2021 The MathWorks, Inc.
2+
3+
import os
4+
import shutil
5+
6+
import pytest
7+
8+
from matlab_proxy import settings
9+
from matlab_proxy.util.mwi import environment_variables as mwi_env
10+
11+
12+
def pytest_generate_tests(metafunc):
13+
os.environ[mwi_env.get_env_name_development()] = "true"
14+
15+
16+
def __get_matlab_config_file():
17+
return settings.get(dev=True)["matlab_config_file"]
18+
19+
20+
def __delete_matlab_config_file():
21+
os.remove(__get_matlab_config_file())
22+
23+
24+
@pytest.fixture(autouse=True, scope="session")
25+
def pre_test_cleanup():
26+
"""A pytest fixture which deletes matlab_config_file before executing tests.
27+
28+
If a previous pytest run fails, this file may have an empty Dict which leads
29+
to the server never starting up matlab.
30+
"""
31+
try:
32+
__delete_matlab_config_file()
33+
except FileNotFoundError:
34+
pass
35+
36+
37+
@pytest.fixture(scope="session", autouse=True)
38+
def cleanup(request):
39+
"""Cleanup the temp directory once we are finished."""
40+
41+
def delete_matlab_test_dir():
42+
# Delete matlab_config_file & its owning directory
43+
matlab_config_file = __get_matlab_config_file()
44+
matlab_config_dir = os.path.dirname(matlab_config_file)
45+
try:
46+
shutil.rmtree(matlab_config_dir)
47+
except FileNotFoundError:
48+
pass
49+
50+
request.addfinalizer(delete_matlab_test_dir)

matlab_proxy/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright (c) 2020-2022 The MathWorks, Inc.
2+
from matlab_proxy.util import system
23

34

45
def get_entrypoint_name():
@@ -34,8 +35,9 @@ def __get_matlab_proxy_base_ddux_value():
3435
Returns:
3536
str : DDUX value for MATLAB use.
3637
"""
38+
current_os = system.get_os().upper()
3739

38-
return "MATLAB_PROXY:BASE:V1"
40+
return f"MATLAB_PROXY:BASE:{current_os}:V1"
3941

4042

4143
def get_mwi_ddux_value(extension_name):

matlab_proxy/app.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ async def create_status_response(app, loadUrl=None):
9595
JSONResponse: A JSONResponse object containing the generic state of the server, MATLAB and MATLAB Licensing.
9696
"""
9797
state = app["state"]
98+
9899
return web.json_response(
99100
{
100101
"matlab": {
@@ -250,20 +251,23 @@ async def termination_integration_delete(req):
250251
Args:
251252
req (HTTPRequest): HTTPRequest Object
252253
"""
254+
logger.debug("Terminating the integration...")
253255
state = req.app["state"]
254256

255257
# Send response manually because this has to happen before the application exits
256258
res = await create_status_response(req.app, "../")
257259
await res.prepare(req)
258260
await res.write_eof()
259261

262+
logger.debug("Shutting down the server...")
260263
# End termination with 0 exit code to indicate intentional termination
261264
await req.app.shutdown()
262265
await req.app.cleanup()
263266
"""When testing with pytest, its not possible to catch sys.exit(0) using the construct
264267
'with pytest.raises()', there by causing the test : test_termination_integration_delete()
265268
to fail. Inorder to avoid this, adding the below if condition to check to skip sys.exit(0) when testing
266269
"""
270+
logger.debug("Exiting with return code 0")
267271
if not mwi_env.is_testing_mode_enabled():
268272
sys.exit(0)
269273

@@ -523,7 +527,8 @@ async def cleanup_background_tasks(app):
523527
# First stop matlab
524528
state = app["state"]
525529
state.clean_up_mwi_server_session()
526-
await state.stop_matlab()
530+
531+
await state.stop_matlab(force_quit=True)
527532

528533
# Stop any running async tasks
529534
logger = mwi.logger.get()
@@ -671,21 +676,23 @@ def main():
671676
app = configure_and_start(app)
672677

673678
loop = util.get_event_loop()
679+
674680
# Add signal handlers for the current python process
675681
loop = util.add_signal_handlers(loop)
676-
loop.run_forever()
682+
try:
683+
loop.run_forever()
684+
except SystemExit:
685+
pass
677686

678687
async def shutdown():
679688
"""Shuts down the app in the event of a signal interrupt."""
680689
logger.info("Shutting down MATLAB proxy-app")
690+
681691
await app.shutdown()
682692
await app.cleanup()
683-
for task in asyncio.Task.all_tasks():
684-
logger.debug(f"calling cancel on all_tasks: {task}")
685-
task.cancel()
686-
await task
687693

688-
asyncio.ensure_future(exit())
694+
# Shutdown any running tasks.
695+
await util.cancel_tasks(asyncio.all_tasks())
689696

690697
try:
691698
loop.run_until_complete(shutdown())

0 commit comments

Comments
 (0)