Android

12 views
Skip to first unread message

Jay Herrmann

unread,
Jul 21, 2011, 11:06:05 PM7/21/11
to pysage
Hi,

I am curious if anyone has used pySage on android?? I was reading
Linux Journal article Python For Android (http://www.linuxjournal.com/
article/10940) about the sl4a (http://code.google.com/p/android-
scripting/)

Jay.

Jay Herrmann

unread,
Jul 23, 2011, 6:18:44 PM7/23/11
to pysage
It looks like the sl4a like did not make the email rap.

So
SL4A
http://code.google.com/p/android-scripting/

P4A
http://code.google.com/p/python-for-android/

So three questions:
1. Anyone try to use pysage on android?
2. If not, John do think that the if I tried to build a module as
talked about on the site.
http://code.google.com/p/python-for-android/wiki/BuildingModules

Would I have any chance of it working?

3. What are the dependencies does pysage have?
As I recall, Python 2.6. and another python lib that I don't recall
at the moment.

Thanks,
Jay.

John Yang

unread,
Jul 24, 2011, 1:50:21 PM7/24/11
to pys...@googlegroups.com
Hi Jay:

Pysage does not have any external dependencies. It works with Python
2.6+ and according to the guide, you should be able to copy it to the
"extra/python" directory.

John

> --
> You received this message because you are subscribed to the Google Groups "pysage" group.
> To post to this group, send email to pys...@googlegroups.com.
> To unsubscribe from this group, send email to pysage+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/pysage?hl=en.
>
>

Jay Herrmann

unread,
Jul 24, 2011, 3:29:30 PM7/24/11
to pys...@googlegroups.com
Thank you.  I will try it.  And let you know what happens.

Jay.

Jay Herrmann

unread,
Jul 27, 2011, 3:10:31 PM7/27/11
to pysage
So here is what I have learned. Copying the pysage to the extras
folder works.

If I use the simple example:

import time
from pysage import Actor, ActorManager, Message

mgr = ActorManager.get_singleton()

class BombMessage(Message):
properties = ['damage']

class Player(Actor):
subscriptions = ['BombMessage']
def handle_BombMessage(self, msg):
print 'I took %s damage from the bomb' %
msg.get_property('damage')

mgr.register_actor(Player(), 'player1')
mgr.queue_message(BombMessage(damage=10))

while True:
processed = mgr.tick()
time.sleep(.03)

Works great.

If I add in the groups it fails.

I post a question to the py4a - python for android group.
http://groups.google.com/group/python-for-android/t/eaa7731cec9af920

I am not sure if the issue is user account support as suggested in the
response. Would you mind reviewing the thread and may be give me some
feedback? I think the issue may be with the python interpreter not
having the "rights" to access some part of the socket bind call.

If you agree that the issue is related to the socket / bind, I will
test out a simple example and post back to the py4a group.

Thanks,
Jay.

John Yang

unread,
Jul 27, 2011, 7:34:19 PM7/27/11
to pys...@googlegroups.com
Jay:

I'm not sure how this is related to user accounts. But the problem is here:

File "/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/
pysage/transport.py", line 265, in listen
self._connection = processing.connection.Listener()

Try doing these 2 lines in the environment:

>>> from multiprocessing import connection
>>> l = connection.Listener()

If this fails, you can try using a different socket family, like:

>>> from multiprocessing import connection
>>> l = connection.Listener(family='AF_INET')

Or maybe try giving it an address. Let me know how this turns out.

BTW, what are you using the group for? I'm considering adding a
feature to pysage which would optionally turn message handlers to
coroutines. This allows you to "yield" without forking an entirely
different process.

John

Jay Herrmann

unread,
Jul 27, 2011, 8:34:38 PM7/27/11
to pys...@googlegroups.com
HI John,

Thanks for the info.  I will try some of your suggests.

For me, I do "need" the process forking.  I am using the forked processing to monitor hardware using the select - waiting for IO completion feature of python.

So the addition of the yielding I don't think will work in my case.  I am also trying to run this on an embedded SBC a TS-7260 from  embeddedarm.com in addition to the android.


Jay.

Jay Herrmann

unread,
Jul 28, 2011, 6:38:09 PM7/28/11
to pys...@googlegroups.com
Hi John,

I changed the IPCTransport.listen def to
 self._connection = processing.connection.Listener(family='AF_INET')
as you had suggestioned and that did fix the socket error. 

The newest error is 
Traceback (most recent call last):
  File "/mnt/sdcard/sl4a/scripts/TestPySage2.py", line 32, in <module>
    mgr.add_process_group('chefs', Chef)      # spawns a new process that "ticks" independently
  File "/mnt/sdcard/com.googlecode.pythonforandroid/extras/python/pysage/system.py", line 383, in add_process_group
    switch = processing.Value('B', 0)
  File "/home/manuel/AptanaStudio3Workspace/python-for-android/python-build/output/usr/lib/python2.6/multiprocessing/__init__.py", li
ne 247, in Value
  File "/home/manuel/AptanaStudio3Workspace/python-for-android/python-build/output/usr/lib/python2.6/multiprocessing/sharedctypes.py"
, line 23, in <module>
AttributeError: 'module' object has no attribute 'c_wchar'

I am going to post my results to the python4android group and see if anyone has any suggestions.

Thanks,
Jay.

Jay Herrmann

unread,
Aug 1, 2011, 4:00:39 PM8/1/11
to pysage
Hi,

Here is the response about the c_wchar. and related.

> <module> AttributeError: 'module' object has no attribute
>'c_wchar'
>This is because we don't have unicode support, 'B' is unsigned byte.
>
>I fixed this problem by doing:
>
>import ctypes
>from _ctypes import _SimpleCData
>
>class c_wchar(_SimpleCData):
> _type_ = 'c'
>
> def __init__(self, *args, **kwargs):
> raise "Not implemented in Android"
>
>ctypes.c_wchar = c_wchar
>
>That fixed the first problem, but raised the next one, which is we don't have semaphores for multiprocessing in Android as bionic doesn't seem to have support for it, sorry but I think you will not be able to use pysage at all.

So John, does Android "missing" semaphores mean the pysage will not
work on Android at the moment or would using the other processing lib
permit it may to work??

Any thoughts.


And as always, thank you so much for your help and insights,
Jay.

John Yang

unread,
Aug 1, 2011, 4:27:09 PM8/1/11
to pys...@googlegroups.com
Jay:

Pysage replies on multiprocessing for its IPC. I see two options
depending on your performance needs:

1. do everything in one process in the pysage main loop. You should
still be able to pool using "select" very quickly. This is the
"yield" feature I was talking about earlier. Sample code below:

class HardwareMonitor(Actor):
def handle_StartPolling(self, msg):
while True:
io = select(...)
if io:
handle_io()
else:
yield

The "yield" here makes this handler method a "coroutine" or
"generator" and as long as it doesn't exist, pysage would include it
in the main loop. If your "handle_io" method does not block, you'll
be just fine.

2. in the case that some parts of this DOES block. You may elect to
run it in a thread.

Here's a sample decorator you can use with your "handle_io" method:

def run_in_thread(fn):
@functools.wraps(fn)
def wrapper(*args, **kws):
t = threading.Thread(target=fn, args=args, kwargs=kws)
t.start()
return wrapper

And you would use it like:

@run_in_thread
def handle_io():
something_that_takes_a_while()

Does that help?

John

Jay Herrmann

unread,
Aug 1, 2011, 9:29:54 PM8/1/11
to pys...@googlegroups.com
Wow, thanks for the two options.  I will write some code and see if I truly under the concepts. If not, I will post a more questions. :) 

Thanks,
Jay.

John Yang

unread,
Aug 1, 2011, 9:49:23 PM8/1/11
to pys...@googlegroups.com
Jay:

Just to be clear. Option #1 still needs to be implemented. But if
you want, you can read up on python generators to get a better
understanding.

John

John Yang

unread,
Aug 1, 2011, 9:52:10 PM8/1/11
to pys...@googlegroups.com
I revised sample code below to remove the "else": (we need to yield
at the end of while loop either way).

class HardwareMonitor(Actor):
def handle_StartPolling(self, msg):
while True:
io = select(...)
if io:
handle_io()

yield

Jay Herrmann

unread,
Aug 1, 2011, 10:53:27 PM8/1/11
to pys...@googlegroups.com
HI John,

I will delay on option 1.

Ok, I will read more about the threading in python.

Thanks.
Jay.

Jay Herrmann

unread,
Aug 2, 2011, 3:48:49 PM8/2/11
to pys...@googlegroups.com
HI,

As I am still learning the ins and outs of Python, I have a few questions about the thread code and the decorator.  Do you know a good link to info on each item, thread and decorator, use in python?  And as I know this is a group for pysage and not a python teaching group, is there a better place to post these questions?  So thank you for taking the time to help me so far.
 
def run_in_thread(fn):
   @functools.wraps(fn)
   def wrapper(*args, **kws):
       t = threading.Thread(target=fn, args=args, kwargs=kws)
       t.start()
   return wrapper

What does the @ symbol do??  Is the run_in_thread in a class or a standalone function?


And you would use it like:

@run_in_thread
def handle_io():
   something_that_takes_a_while()

Thanks,
Jay.

John Yang

unread,
Aug 2, 2011, 4:53:06 PM8/2/11
to pys...@googlegroups.com
Jay:

In short, decorator is a function that wraps another function. Link
below will explain much better than I do:

http://www.python.org/dev/peps/pep-0318/

The "@" sign makes the code clearer. As you are exploring this
option, please provide sample code when you've reached a good point of
your use case. Keep in mind, you do need to ensure that the code ran
in the thread will be thread-safe. This is the trade off compared to
option #1.

John

Jay Herrmann

unread,
Aug 2, 2011, 5:41:46 PM8/2/11
to pys...@googlegroups.com
Hi John,

Thank you for the link.  I will review it.

I do my best to take baby steps. And will provide sample code as I move forward.

Jay.

Jay Herrmann

unread,
Aug 5, 2011, 11:04:44 PM8/5/11
to pys...@googlegroups.com
Hi John,

An update on my process. I did a little research as I am still learning python.  Your suggestions provided a place to start looking and playing.

The following used a decorator and threading.  The first is in sync with your example minus the functtools.wrapper
http://amix.dk/blog/post/19346

As I was thinking about the process, I was not sure how inter-thread communication would work in python.  A search turned up the link below.


  • Do you see any red flags in the ClassQueue Class related to use with pysage?
  • Do you think I could add the following to an Actor update?
    if not cq.is_done():
        for cqitem in cq.get_next_collected():       #harvest
           mgr.queue_message_to_group( mgr.PYSAGE_MAIN_GROUP, MyMessage( cqitem.args, cqitem.get_return()))

Jay.

John Yang

unread,
Aug 7, 2011, 6:58:35 PM8/7/11
to pys...@googlegroups.com
Jay:

Pysage isn't thread safe because it doesn't lock.  So pysage calls like "queuemessage" within your thread isn't safe.  A thread in pysage should be restricted to localized functions.

Having said that, you may use a thread safe queue to synchronize data between the 2 threads.  It kind of defeats the purpose of message passing and should be avoided if possible.

With some improvement, pysage can offer thread safe local queuing without locking.  But functions such as "tick" will definitely not be thread safe.

HTH,

John
--
Reply all
Reply to author
Forward
0 new messages