Repository: mars-project/mars

Issue:
[BUG] Task failed with AttributeError: '_LogWrapper' object has no attribute 'flush'
<!--
Thank you for your contribution!

Please review https://github.com/mars-project/mars/blob/master/CONTRIBUTING.rst before opening an issue.
-->

**Describe the bug**

Task failed with AttributeError: '_LogWrapper' object has no attribute 'flush'.

**To Reproduce**
To help us reproducing this bug, please provide information below:
1. Your Python version
2. The version of Mars you use
3. Versions of crucial packages, such as numpy, scipy and protobuf
4. Full stack of the error.
5. Minimized code to reproduce the error.

```python
Traceback (most recent call last):
  File "/home/admin/work/public-mars-0.5.2.zip/mars/promise.py", line 100, in _wrapped
  File "/home/admin/work/public-mars-0.5.2.zip/mars/worker/calc.py", line 304, in <lambda>
  File "/home/admin/work/public-mars-0.5.2.zip/mars/worker/calc.py", line 278, in _start_calc
  File "/home/admin/work/public-mars-0.5.2.zip/mars/utils.py", line 365, in _wrapped
  File "/home/admin/work/public-mars-0.5.2.zip/mars/worker/calc.py", line 202, in _calc_results
  File "src/gevent/event.py", line 383, in gevent._gevent_cevent.AsyncResult.result
  File "src/gevent/event.py", line 305, in gevent._gevent_cevent.AsyncResult.get
  File "src/gevent/event.py", line 335, in gevent._gevent_cevent.AsyncResult.get
  File "src/gevent/event.py", line 323, in gevent._gevent_cevent.AsyncResult.get
  File "src/gevent/event.py", line 303, in gevent._gevent_cevent.AsyncResult._raise_exception
  File "/opt/conda/lib/python3.7/site-packages/gevent/_compat.py", line 65, in reraise
  File "/opt/conda/lib/python3.7/site-packages/gevent/threadpool.py", line 142, in __run_task
  File "mars/actors/pool/gevent_pool.pyx", line 127, in mars.actors.pool.gevent_pool.GeventThreadPool._wrap_watch.inner
    result = fn(*args, **kwargs)
  File "/home/admin/work/public-mars-0.5.2.zip/mars/executor.py", line 690, in execute_graph
  File "/home/admin/work/public-mars-0.5.2.zip/mars/executor.py", line 571, in execute
  File "/opt/conda/lib/python3.7/concurrent/futures/_base.py", line 435, in result
  File "/opt/conda/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
  File "/opt/conda/lib/python3.7/concurrent/futures/thread.py", line 57, in run
  File "/home/admin/work/public-mars-0.5.2.zip/mars/utils.py", line 439, in _inner
  File "/home/admin/work/public-mars-0.5.2.zip/mars/executor.py", line 443, in _execute_operand
  File "/home/admin/work/public-mars-0.5.2.zip/mars/executor.py", line 641, in handle
  File "/home/admin/work/public-mars-0.5.2.zip/mars/custom_log.py", line 125, in wrap
  File "/home/admin/work/public-mars-0.5.2.zip/mars/utils.py", line 1121, in wrapped
  File "/home/admin/work/public-mars-0.5.2.zip/mars/dataframe/groupby/apply.py", line 71, in execute
  File "/opt/conda/lib/python3.7/site-packages/pandas/core/groupby/groupby.py", line 736, in apply
  File "/opt/conda/lib/python3.7/site-packages/pandas/core/groupby/groupby.py", line 752, in _python_apply_general
  File "/opt/conda/lib/python3.7/site-packages/pandas/core/groupby/ops.py", line 206, in apply
  File "<pyodps_user_code>", line 212, in run
    return run_batch(df, 0, len(df))
  File "<pyodps_user_code>", line 118, in run_batch
    explainer = shap.KernelExplainer(h(p_XYData), p_XData)
  File "/opt/conda/lib/python3.7/contextlib.py", line 119, in __exit__
  File "<pyodps_user_code>", line 101, in timeit
    sys.stdout.flush()
AttributeError: '_LogWrapper' object has no attribute 'flush'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "<pyodps_user_code>", line 221, in <module>
    result.execute()
  File "/home/tops/lib/python3.7/site-packages/mars/core.py", line 628, in execute
    return run()
  File "/home/tops/lib/python3.7/site-packages/mars/core.py", line 624, in run
    self.data.execute(session, **kw)
  File "/home/tops/lib/python3.7/site-packages/mars/core.py", line 375, in execute
    return run()
  File "/home/tops/lib/python3.7/site-packages/mars/core.py", line 370, in run
    session.run(self, **kw)
  File "/home/tops/lib/python3.7/site-packages/mars/session.py", line 478, in run
    result = self._sess.run(*tileables, **kw)
  File "/home/tops/lib/python3.7/site-packages/mars/web/session.py", line 214, in run
    if self._check_response_finished(graph_url, timeout_val):
  File "/home/tops/lib/python3.7/site-packages/mars/web/session.py", line 174, in _check_response_finished
    raise ExecutionFailed('Graph execution failed.') from exc
mars.errors.ExecutionFailed: 'Graph execution failed.'
```



Discussion:

Resolving patch:
diff --git a/mars/custom_log.py b/mars/custom_log.py
--- a/mars/custom_log.py
+++ b/mars/custom_log.py
@@ -96,6 +96,9 @@ def write(self, data):
         # write into previous stdout
         self.stdout.write(data)
 
+    def flush(self):
+        self.stdout.flush()
+
 
 def gen_log_path(session_id, op_key):
     filename = f"{str(session_id).replace('-', '_')}_{op_key}"


Test patch:
diff --git a/mars/scheduler/tests/integrated/test_normal_execution.py b/mars/scheduler/tests/integrated/test_normal_execution.py
--- a/mars/scheduler/tests/integrated/test_normal_execution.py
+++ b/mars/scheduler/tests/integrated/test_normal_execution.py
@@ -369,6 +369,7 @@ def f():
             # test multiple functions
             def f1(size):
                 print('f1' * size)
+                sys.stdout.flush()
 
             fs = ExecutableTuple([spawn(f1, 30), spawn(f1, 40)])
             fs.execute(session=sess)