Can not understand Interleaving pattern.

83 views
Skip to first unread message

Mithril

unread,
Aug 2, 2016, 10:05:36 AM8/2/16
to Tornado Web Server
>Sometimes it is useful to save a Future instead of yielding it immediately, so you can start another operation before waiting:
```
@gen.coroutine
def get(self):
    fetch_future = self.fetch_next_chunk()
    while True:
        chunk = yield fetch_future
        if chunk is None: break
        self.write(chunk)
        fetch_future = self.fetch_next_chunk()
        yield self.flush()
```

To me, the normal `yield` use case is just to avoid load big data into memory. `yield` can be described as a pause and return mark. While looping generator,  call `next()` function go into the generator,  once touch `yield` , return the value and pause at here, then go to next call....

But the example code I can't understand. 

1. Doesn't `self.fetch_next_chunk()`  return `Future`? 
    
    In `Future` example: 

    ```
    from tornado.concurrent import Future

    def async_fetch_future(url):
        http_client = AsyncHTTPClient()
        my_future = Future()
        fetch_future = http_client.fetch(url)
        fetch_future.add_done_callback(
            lambda f: my_future.set_result(f.result()))
        return my_future
    ```

    It need `f.result()` to get the result.  But `chunk` seems already be the `fetch_future.result()` , why ?

2. `chunk = yield fetch_future` 

    How do tornado asign `fetch_future` to `chunk`, it is not the normal `yield` I known!

    I have write a test:

    ```
    def test(x=3):
        while x:
            a = yield x
            x-=1
            print a

    for i in test():
        print 'x', i
    ```

    output:

    ```
    x 3
    None
    x 2
    None
    x 1
    None
    ```

3. `yield self.flush()`

    What's the meaning of `self.flush()`,  flush often point to write `buffer` to file/memory, would not return `buffer` itself .


I just feel very confuse about the example code, because I have a strong imagine about `yield` would return someting (which touble me to understand that code I think.)

Ben Darnell

unread,
Aug 2, 2016, 11:00:46 PM8/2/16
to python-...@googlegroups.com
Yes. `yield` (in a `tornado.gen.coroutine`) turns a `Future` into its `result()` (without blocking).
 

2. `chunk = yield fetch_future` 

    How do tornado asign `fetch_future` to `chunk`, it is not the normal `yield` I known!

`yield` was changed from a statement to an expression in PEP 342; that's where all of this functionality comes from: https://www.python.org/dev/peps/pep-0342/

`@tornado.gen.coroutine` is a decorator that makes all `yield` expressions in the wrapped function turn Futures into results.
 

    I have write a test:

    ```
    def test(x=3):
        while x:
            a = yield x
            x-=1
            print a

    for i in test():
        print 'x', i
    ```

    output:

    ```
    x 3
    None
    x 2
    None
    x 1
    None
    ```

3. `yield self.flush()`

    What's the meaning of `self.flush()`,  flush often point to write `buffer` to file/memory, would not return `buffer` itself .

`self.flush()` writes the buffer to the network. It returns a Future whose result is None, but that result isn't returned until the entire buffer has been written to the network. 

-Ben
 


I just feel very confuse about the example code, because I have a strong imagine about `yield` would return someting (which touble me to understand that code I think.)

--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornad...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages