rgalanakis / goless Goto Github PK
View Code? Open in Web Editor NEWGo-like semantics built on top of Stackless Python.
License: Apache License 2.0
Go-like semantics built on top of Stackless Python.
License: Apache License 2.0
def casing_test2():
import time
from datetime import datetime
def server1(ch):
time.sleep(6)
ch.send('from server 1')
def server2(ch):
time.sleep(2)
ch.send('from server 2')
def main():
output1 = goless.chan()
output2 = goless.chan()
cases = [goless.rcase(output1), goless.rcase(output2)]
goless.go(server1, output1)
goless.go(server2, output2)
# will iterate through all cases, and execute the pick the first available case
chosen, value = goless.select(cases)
print(chosen)
print(value)
main()
casing_test2()
Outputs:
<goless.selecting.rcase object at 0x7fcbacccf390>
from server 1
The returned result should actually be.
from server 2
Can you explain why this is not working as it should ???
server2 would exit first because it is only sleep for 2 seconds, which is faster than server1 6 seconds.
It'd be interesting to write the existing benchmarks in Go and see how their performance compares.
The select function will detect a deadlock condition (see #25), but this only happens before it starts to loop and wait for a channel to be ready. So the code could potentially get past this check, then a greenlet dies, and there's an undetected deadlock.
This choice was made because the deadlock detection is expensive in gevent. It requires looping over gc.get_objects() and looking for alive greenlets.
If that detection process could be sped up, the check could happen inside the select loop, and a deadlock could be more reliably detected.
Don't forget to improve the documentation.
I've been mulling the need to coordinate a few processes on different machines.
Is something like this on the roadmap?
Although I use MQTT for cross-language message passing (and am happy with it), it would be interesting if one could set up channels across machines using something that is more popular (say Redis, which is popping up all over the place these days, or 0MQ, which is also fairly agnostic).
Hi,
while I appreciate the existence of this code, it has the flaw of making
people think that they can simply use Goless to have the GoLang
power at their fingertips in Python for free.
That is definitely not true, and it will not ever become true, unless Stackless
comes up with a different concurrence scheme and a good work-around for the GIL.
I think the existence of the GIL and it shortcomings should be mentioned
at the frontpage, in README.md, to avoid tricking people into assuming
things that are not true.
Goless is a fine example of a Go-like dialect, but it is much less than that.
And there is no evidence that this will change in the near future.
I would be more than happy if it was not so, still trying... ;-)
Cheers - Chris
Do you intend to implement some GO standard packages?
For example, "sync" package is quite useful. It is more efficient to implement if you know the goless' back-end.
Do we need a threading backend? Or how can we take advantage without a thread per go routine?
the error is
Exception KeyError: KeyError(41882928,) in <module 'threading' from 'C:\Python27\Lib\threading.pyc'> ignored
and this is my code https://gist.github.com/codeskyblue/1b8dca59879b193a200d
When running benchmark.py as found in master, a SystemError is raised:
SystemError: (libev) select: Unknown error
Traceback (most recent call last):
File "C:\Users\zeev\Desktop\goless\benchmark.py", line 111, in <module>
main()
File "C:\Users\zeev\Desktop\goless\benchmark.py", line 105, in main
prime()
File "C:\Users\zeev\Desktop\goless\benchmark.py", line 100, in prime
bench_selects()
File "C:\Users\zeev\Desktop\goless\benchmark.py", line 68, in bench_selects
took_nodefault = bench_select(False)
File "C:\Users\zeev\Desktop\goless\benchmark.py", line 62, in bench_select
selecting.select(cases)
File "C:\Users\zeev\Desktop\goless\goless\selecting.py", line 93, in select
_be.yield_()
File "C:\Users\zeev\Desktop\goless\goless\backends.py", line 138, in yield_
gevent.sleep()
File "C:\Python27\lib\site-packages\gevent\hub.py", line 73, in sleep
waiter.get()
File "C:\Python27\lib\site-packages\gevent\hub.py", line 569, in get
return self.hub.switch()
File "C:\Python27\lib\site-packages\gevent\hub.py", line 332, in switch
return greenlet.switch(self)
SystemError: (libev) select: Unknown error
would_deadlock
passes and this consistently happens at the 495 itteration (at least for me).
I'm running the code on Windows 7 with the gevent backend, and gevent==1.0.1, greenlet==0.4.2.
I seem to be getting a SystemError at the END of my script. There isn't any error in the output or operation even. Just simply annoying to have a SystemError get thrown at the end.
SystemError: (libev) select: Unknown error
Traceback (most recent call last):
File "golex.py", line 233, in <module>
token = tokens.recv()
File "c:\Python27\lib\site-packages\goless\channels.py", line 53, in recv
got = self._recv()
File "c:\Python27\lib\site-packages\goless\channels.py", line 153, in _recv
value = self.waiting_chan.receive()
File "c:\Python27\lib\site-packages\goless\backends.py", line 78, in receive
return self.get()
File "c:\Python27\lib\site-packages\gevent\queue.py", line 477, in get
return waiter.get()
File "c:\Python27\lib\site-packages\gevent\hub.py", line 568, in get
return self.hub.switch()
File "c:\Python27\lib\site-packages\gevent\hub.py", line 331, in switch
return greenlet.switch(self)
SystemError: (libev) select: Unknown error
I'm not completely sure where it stems from, but it could be an error in gevent or even greenlet as well. Is there a fix that I haven't heard about for this?
I have a data_process
function, it will continue running to process a data stream.
And there are a bundle of streams, so I want use goless.go
to process them in parallel .
But, I found if there is "While True" in the routine, only the first routine is started.
Is the a way to start all of them ?
Until stackless problems are fixed.
>>> from goless import *
>>> from gevent import *
>>> ch = chan()
>>> def foo():
try:
while True:
r = ch.recv()
print(r)
if r == 'raise':
raise Exception
sleep(1)
except:
print('exception raised')
>>> go(foo)
>>> ch.send('hello')
hello
>>> ch.send('world')
world
>>> ch.send('raise')
raise
exception raised
>>> go(foo)
>>> ch.send('hello')
hello
>>> ch.close() # no printing of 'exception raised'
>>> ch.send('hello')
Traceback (most recent call last):
File "<pyshell#158>", line 1, in <module>
ch.send('hello')
File "C:\Python38\lib\site-packages\goless\channels.py", line 36, in send
raise ChannelClosed()
goless.channels.ChannelClosed
>>> ch = chan()
>>> ch.send('world') # receiver still receives from this new channel
world
This go program works:
package main
import "fmt"
import "time"
func main() {
ch := make(chan int)
ch2 := make(chan int)
ch3 := make(chan int)
go func() {
select {
case i := <-ch:
fmt.Println("Received", i, "from main channel")
case i := <-ch2:
fmt.Println("Received", i, "from ch2, how odd")
}
}()
go func() {
select {
case ch <- 1:
fmt.Println("Written 1 to main channel")
case ch3 <- 1:
fmt.Println("Written 1 to ch3, how odd")
}
}()
time.Sleep(100)
}
The runtime figures out which channel operation can proceed, and it does:
Written 1 to main channel
Received 1 from main channel
The equivalent goless program doesn't work:
import gevent
import goless
ch = goless.chan()
ch2 = goless.chan()
ch3 = goless.chan()
def read():
cases = [goless.rcase(ch), goless.rcase(ch2)]
case, val = goless.select(cases)
print case, val
def write():
cases = [goless.scase(ch, 1), goless.scase(ch3, 1)]
case, val = goless.select(cases)
print case, val
goless.go(read)
goless.go(write)
gevent.sleep(1)
Nothing is printed.
From checking the source code, it looks like performing a select never adds anything to the channels which are ready to read or to write, only an unconditional ch.send() or ch.recv() will do that, so it's not possible for two selects on either end of an unbuffered channel to ever proceed.
This is a pretty big departure from how unbuffered channels work in go. It seems that this is either a bug to be fixed, or should be mentioned in the documentation.
As suggested in #8, this is for creating a release pipeline/process.
I'm trying to use goless with gevent and want to make sure the tests pass before relying on it.
I couldn't find any documentation on how to run the tests, so I'm running them as follows:
virtualenv venv
. venv/bin/activate
pip install pytest mock gevent
pytest tests -v
All tests pass except tests/test_select.py::SelectTests::test_raises_deadlock_if_no_goroutines
, which seems to hang indefinitely.
> python --version
Python 2.7.13
Not sure if this is a known issue (and it's not necessarily a showstopper since one should avoid the particular scenario being tested anyways) but pointing it out just in case.
Is it just me or is there no way to hand off parameters to goroutines? I've been looking at https://github.com/benoitc/offset, which supports that (and goes a bit further down the stack in terms of scheduling), and was wondering if that's planned, since goless seems a little lighter-handed in terms of runtime.
Once we get some more eyes on the code, let's upload some release to PyPI for more use.
As requested by @rcarmo in #6 (comment)
This is great, and much nicer than my homegrown threading solution. How difficult would it be to mix in a threading back-end?
By looking at the open issues it seems like all of them are "taken" even though not all are assigned.
If I'm not mistaken in that sense we need more issues so that I can work on something! I'm currently out of ideas myself of what to do... Maybe try to create the join-pattern-OMG? ;)
[x] Bug (Typo)
priotity
, however expect to see priority
.enviroments
, however expect to see environments
.autodoec
, however expect to see autodoc
.Semi-automated issue generated by
https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md
To avoid wasting CI processing resources a branch with the fix has been
prepared but a pull request has not yet been created. A pull request fixing
the issue can be prepared from the link below, feel free to create it or
request @timgates42 create the PR. Alternatively if the fix is undesired please
close the issue with a small comment about the reasoning.
https://github.com/timgates42/goless/pull/new/bugfix_typos
Thanks.
See #31
This is failing for Python3 because gevent must be installed from github.
If I put everything in a single index.rst, there is no ToC and thus no navigation on RTD (navigation in default Sphinx theme is there). If I split it up how it is now (body.rst is included by index.rst), navigation isn't so great (sidebar links to body.html, refs in text link to index.html). I think I need to set up the RTD theme locally and test out some config changes.
I'm trying out goless, but I'm not sure if it's working for me as intended. I expect to get interleaved output from this program:
import goless
import time
def one():
while True:
time.sleep(1)
print('one')
def two():
while True:
time.sleep(1)
print('two')
goless.go(one)
goless.go(two)
print('Launched both')
goless.chan().recv()
But I get this output:
Launched both
one
one
one
one
one
one
one
one
one
one
one
^C
Is this expected, or something wrong with the way I'm using goless?
Stackless Python 2.7 works fine, as does vanilla 2.7 with gevent, but we get terrible behavior under PyPy with stackless/continulets. We need to figure out what is up.
When using the stackless backend, we use the runcount
attribute to detect deadlocks.
Sadly, PyPys stackless module doesn't provide that attribute and crushes when trying to detect a potential deadlock.
(PyPy 2.3.1 x32 for Windows, GOLESS_BACKEND=stackless)
tox.ini uses the tip of surfly/gevent for PyPy because 1.0.1 doesn't support it.
Much worse, the 3.3 environment is a total mess, because Cython wouldn't install before gevent on travis, so cython is in deps, and gevent is installed as a command. However the removal of gevent as a dependency meant that setup,py egg_info
couldn't be run (explicit backend set but not valid raises error), so the GOLESS_BACKEND
var is nulled out. To top off the cake, travis couldn't find coverage, so tox just runs nosetests.
Rather than debug this crap (I tried!), let's just wait for gevent.
I am not sure what'd be involved, but it would be nice if goless had asyncio support. I'm not sure what that means since I haven't looked into it much, so please educate me (or start a pull request).
I've been playing with the library and I'm enjoying it immensely, but there's one thing that bugs me - why does select
take a list? Sure, that's the way go
does it but it's much more Pythonic IMO for it to take an *args
argument.
A second point, of which I'm less sure, is that it seems the case used most often for select
is rcase
, that is, waiting on a result from a channel. I think it would be nice if I could pass a channel object and get it wrapped with an rcase
as a default behavior.
So, to recap, I propose:
case, val = goless.select(c1, c2)
Instead of:
case, val = goless.select([goless.rcase(c1), goless.rcase(c2)])
Also, since this would make that switching pattern suggested in the docs less elegant to implement, complementary is_receive
, is_send
and is_default
methods could be added for testing the case
return value.
If this sounds good to you, I'd be happy to make a pull request with the suggested changes.
Pointed out by Chris Huegle (@chuegle) via email.
Running 'goless' version 0.7.2 on Windows 7 under PyPy 2.5.0 in some very simple code leads to an AttributeError
bubbling up out of stackless. The traceback is here:
C:\Users\cb2\tmp>pypy golesstest.py
CRITICAL:root:['Traceback (most recent call last):\n', ' File "C:\\pypy-2.5.0-win32\\site-packages\\goless\\__init__.py", line 58, in safe_wrapped\n f(*args, **kwargs)\n', "TypeError: 'NoneType' object is not callable\n"]
Traceback (most recent call last):
File "app_main.py", line 75, in run_toplevel
File "golesstest.py", line 37, in <module>
request_collation(inchan, outchan)
File "golesstest.py", line 29, in request_collation
for response in outchan:
File "C:\pypy-2.5.0-win32\site-packages\goless\channels.py", line 97, in next
return self._next()
File "C:\pypy-2.5.0-win32\site-packages\goless\channels.py", line 88, in _next
return self.recv()
File "C:\pypy-2.5.0-win32\site-packages\goless\channels.py", line 53, in recv
got = self._recv()
File "C:\pypy-2.5.0-win32\site-packages\goless\channels.py", line 153, in _recv
value = self.waiting_chan.receive()
File "C:\pypy-2.5.0-win32\site-packages\goless\backends.py", line 79, in receive
return stackless.channel.receive(self)
File "C:\pypy-2.5.0-win32\lib_pypy\stackless.py", line 323, in receive
return self._channel_action(None, -1)
File "C:\pypy-2.5.0-win32\lib_pypy\stackless.py", line 307, in _channel_action
schedule()
File "C:\pypy-2.5.0-win32\lib_pypy\stackless.py", line 524, in schedule
_scheduler_switch(curr, task)
File "C:\pypy-2.5.0-win32\lib_pypy\stackless.py", line 150, in _scheduler_switch
next.switch()
File "C:\pypy-2.5.0-win32\lib_pypy\stackless.py", line 65, in switch
current._frame.switch(to=self._frame)
File "C:\pypy-2.5.0-win32\lib_pypy\stackless.py", line 53, in run
return func(*argl, **argd)
File "C:\pypy-2.5.0-win32\lib_pypy\stackless.py", line 415, in _func
func(*argl, **argd)
File "C:\pypy-2.5.0-win32\site-packages\goless\__init__.py", line 60, in safe_wrapped
on_panic(*_sys.exc_info())
File "C:\pypy-2.5.0-win32\site-packages\goless\__init__.py", line 41, in on_panic
_be.propagate_exc(SystemExit, 1)
File "C:\pypy-2.5.0-win32\site-packages\goless\backends.py", line 108, in propagate_exc
stackless.getmain().throw(errtype, *args)
AttributeError: 'tasklet' object has no attribute 'throw'
In practice, this is probably to do with stackless.py
that PyPy 2.5.0 makes available. In particular, it really does seem not to have the throw
method.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.