Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Python ➜ mushclient + python + multithreading = boom

mushclient + python + multithreading = boom

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1 2  

Posted by Shwick   (21 posts)  Bio
Date Thu 27 May 2010 01:21 AM (UTC)

Amended on Thu 27 May 2010 01:25 AM (UTC) by Shwick

Message
I need to put some random delays in between my commands.

DoAfter isn't cutting it; if I have consecutive triggers with commands to send, DoAfter can mix up the commands.

After reading faq #25 and seeing lua coroutines talked about, I tried threads in python with timer.sleep().

Every time world.Note() is called within the thread, mushclient crashes, even if I use semaphores to limit it to one thread of execution.

Is there a way to code python threads within Mushclient?

test class

import threading

#thread class
class ThreadTest(threading.Thread):        
    
    def __init__(self):
        threading.Thread.__init__(self)
        
    def run(self):
        self.sendHi()

    def sendHi(self):
        world.Note('hi')

#alias
def testIt(thename, theoutput, wildcards):
    world.Note("testIt called")
    t = ThreadTest()
    try:
        t.start()
    except:
        world.Note("Unexpected error:", sys.exc_info()[0])
        raise


result

testIt called
hi


then crash
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #1 on Thu 27 May 2010 01:29 AM (UTC)

Amended on Thu 27 May 2010 01:32 AM (UTC) by Twisol

Message
You could try keeping a queue of commands to send, and a timer that sends the next command when it fires. To add randomness, have the timer change its own delay every time it's fired.

EDIT: I have no idea on the threading thing. If it's any consolation, you'd probably have a nondeterministic order of commands in Lua, too. It's a timer thing, not a language thing.

EDIT 2: Lua coroutines aren't really "threads", they're more like fibers. Only one ever executes at a time, and they cooperate by explicitly passing control. Normal threads (which I assume Python uses) are preemptive rather than cooperative, which leads to the usual mess.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #2 on Thu 27 May 2010 02:37 AM (UTC)
Message
I am no Python expert, but all I can suggest is make a queue of some sort, and use DoAfterSpecial to call a routine that pulls out the top item from the queue, then reschedules for the next one and so on. At least they will be done in order then.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Shwick   (21 posts)  Bio
Date Reply #3 on Thu 27 May 2010 02:53 AM (UTC)

Amended on Thu 27 May 2010 02:54 AM (UTC) by Shwick

Message
omg it works thank you so much Twisol, perfect solution

PHEW

thought i would have to switch to lua for a second there

god forbid

also thanks Nick for continuous posts helping me get through this quickly
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #4 on Thu 27 May 2010 02:55 AM (UTC)
Message
Shwick said:

omg it works thank you so much Twisol, perfect solution

PHEW

thought i would have to switch to lua for a second there

god forbid

also thanks Nick for continuous posts helping me get through this quickly


*rofl* No problem!

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by CJI   Poland  (7 posts)  Bio
Date Reply #5 on Tue 13 Jul 2010 12:19 PM (UTC)

Amended on Wed 14 Jul 2010 07:24 AM (UTC) by CJI

Message
Hi!

First thing first - sorry for my bad english, please try to understand me :)

Now to the point - Python threads are not real threads - there is this thing called GIL (Global Interpreter Lock) so at any given time only one thread is running, even on multicore or multiprocessor machine. Switching between 'threads' is done by interpreter every now and then - it's done behind the scenes, and it results in python interpreter running always in one OS level thread, which is good for embedding (I think).

Now, the odd thing is that no amount of Locks, Queues, Semaphores, whatevers - enables one to use Python threads in MUSHClient. MC either blows (program has stopped working) or other threads (besides main) don't run at all.

Consider this code:


import subprocess, time
from threading import Lock, Thread, enumerate as tenum

global_lock = Lock()

def now():
    with global_lock:
        return time.time()

def note( *args ):
    with global_lock:
        s = "".join( [ str( x ) for x in args ] )
        world.Note( s )

def t():
    for i in range( 50 ):
        note( "It's now ", now(), " since epoch" )
        time.sleep( 2 )

note( tenum(), " ", now() )

t = Thread( target = t )
t.start()

note( tenum(), " ", now() )


It really SHOULD work! But it does not. MC stops responding immediately after opening the world. After trying many various approaches, I had to give up - there's something wrong with hardcode or possibly python com extension. Of course multithreading isn't a 'must have' for me, there are plenty of techniques (including coroutines, implemented in python via generators) or subprocesses (which work), but still - this is a bug somewhere. Sorry, Nick, I had to tell you about it ;)

Last thing - there is one thing I can think of that requires some kind of concurency (it's much harder without it) - and I mean doing some very heavy computations in background. Well, I have written quick test:


import subprocess, time

def note( *args ):
    s = "".join( [ str( x ) for x in args ] )
    world.Note( s )

p = subprocess.Popen( [ "ping", "-t", "wp.pl" ], stdout = subprocess.PIPE )
count = 0

def timer( *args ):
    global count
    count += 1
    if count >= 70:
        p.kill()
        return
    note( p.stdout.read( 10 ) )


Which works perfectly (with timer invoking timer routine), producing expected output:


Badanie 
wp.pl [212
.77.100.10
1] z 32 ba
jtami dany
ch:
Odpow
ied« z 212
.77.100.10
1: bajt˘w=
32 czas=34
ms TTL=248


and MC is still responding :)

I'm currently writing python framework for MC scripting, so expect me to post here once in a while.

One additional question - is python interpreter in MC ever restarted? I hate it when I have to write something this ugly:

    import sys, os

    SCRIPTS_PATH = "C:\Users\cji\Desktop\MUSHclient\python"
    sys.path.insert( 0, SCRIPTS_PATH )

    import world_wrap; reload( world_wrap )
    world_wrap.init( world )

    import trigreg
    import printer
    import constants

    # I mean THIS ugly:
    def reload_modules():
        for name, m in globals().iteritems():
            try:
                if name == "world_wrap":
                    continue
                __import__( name )
                printer.printf( "reloading %s\n" % name )
                reload( m )
            except:
                pass
    reload_modules()


just because Ctrl+Alt+R seems to reload script file without restarting interpreter.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #6 on Tue 13 Jul 2010 08:50 PM (UTC)
Message
Quote:

for i in range( 50 ):
note( "It's now ", now(), " since epoch" )
time.sleep( 2 )


Assuming this does what it looks like, I wouldn't do it. In any language, doing a sleep basically just hangs the interpreter, and in your case it looks like you will do it for 100 seconds (50 * 2).

I don't want to push Lua when you obviously want to use Python, but the only real way of doing similar code, that I know of, is to use Lua coroutines. These are a form of co-operative multi-tasking, where coroutines yield execution at places of your choice.

As for the bug, if someone can point it out I'll be happy to fix it, but the fact is that all of the WSH (Windows Script Host) scripting is done exactly the same way. It is the same code, and the only difference is the GUID of the script engine which is selected. There is no real possibility for a "Python bug", only a bug that affects all script engines. However scripting has been active for quite a while now (like, years) and no-one else complains.

Lua is implemented differently, because for one thing, there is (or was) no WSH interface for Lua. So I wrote "glue" routines that connect the Lua calls to the underlying functions that the other script engines use.

Some WSH implementors have difficulty getting it right, for example a while back if you made a compile error in PHP, the entire client simply exited. This only happened in PHP, and I assume that the script writers thought they could display an error message and "exit program" the same way they normally do. However that is a bit unfriendly to the host program.

CJI said:

One additional question - is python interpreter in MC ever restarted? I hate it when I have to write something this ugly ...


Reloading the script file should (does) recreate the script engine. The old engine is "deleted" (in the C++ sense) and a new one started from scratch. Then the script file is reloaded into the new engine, effectively setting all variables and settings back to the default state.

However, if the Python DLL has some "memory" itself, then possibly it will not behave the same as the first time. Again, all script languages other than Lua are done the same way.

A Google for "Python threading WSH" seems to indicate that other people are having problems with Python, threading, and the WSH implementation.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by CJI   Poland  (7 posts)  Bio
Date Reply #7 on Wed 14 Jul 2010 09:10 AM (UTC)

Amended on Wed 14 Jul 2010 09:54 AM (UTC) by CJI

Message
Nick Gammon said:

Quote:

for i in range( 50 ):
note( "It's now ", now(), " since epoch" )
time.sleep( 2 )


Assuming this does what it looks like, I wouldn't do it.


It works fine in Python. time.sleep() does 'hang' - but only current thread, not the whole interpreter. Try it on Python interactive prompt or - alternatively - just believe me ;)

Nick Gammon said:
is to use Lua coroutines.


Argh! To ... with Lua! (Meaning - I know basics of this language, but I just don't want to use it if I don't have to.) Coroutines are very easy to implement in Python, there are even few external libraries ready to use, but if you want lightweight coroutines you can just use Python native generators. In Lua docs there is comparision of coroutines with generators - but it's very outdated and I'm sure that nowadays there is no single thing you can achieve with coroutines that you can not with generators.

But that's not the point - various techniques, like coroutines or deferreds in Twisted are nice, of course, but are NOT threads. You can not use ANY blocking operation in coroutines, while you can do this in separate thread. Let's say I want to read some data from open socket - socket.recv( 1024 ) will block, if there is no data to read, stopping all scripting. Of course, you can use non-blocking socket and check if there is some data, reading it only when necessary - but using separate thread is simpler.

Nick Gammon said:

There is no real possibility for a "Python bug", only a bug that affects all script engines. However scripting has been active for quite a while now (like, years) and no-one else complains.


It's very easy to explain - only Ruby offers threads similar to Python's and my guess is that they don't work either, but scripting with Ruby is even less popular (I think) than with Python. I'm not sure about PERL (googled - it has threading, done with starting new interpreter for each thread. If I was a betting person I'd say it doesn't work either), but JS and friends are (I think?) single threaded by nature. Quick googling:
Quote:
PHP has no built in support for threading.

Quote:
There's no true threading in JavaScript.

and so on.

Nick Gammon said:

However, if the Python DLL has some "memory" itself,


It probably has - import statements are cached and this cache seems to be cleared only when MUSHClient is restarted.

Quote:

Again, all script languages other than Lua are done the same way.


Well, I can live with that, no big deal. With my reloading routine and occasional restarts while developing it's just a bit uncomfortable. The 'world' object is accessible only in one file, but hey - I wrote simple wrapper module, which - if initialised - is importable everywhere and is friendlier than original, printing meaning of return code if not equal to 0 automatically.
[I can't resist:

class Wrapper( object ):
    def __init__( self, w ):
        self.world = w

    def __getattr__( self, name ):
        if not hasattr( self.world, name ):
            raise Exception( "No such method or attribute!" )

        attr = getattr( self.world, name )
        if not callable( attr ):
            return attr

        func = attr

        def wrap( *args, **kwargs ):
            ret = func( *args, **kwargs )
            if ret is None:
                ret = 0

            try:
                msg = smart_ret[ int( ret ) ]
            except:
                return ret

            if ret != 0:
                self.world.note( name )
                self.world.note( msg )

            return msg
        return wrap

com = None

def init( world ):
    global com
    com = Wrapper( world )


beautiful, isn't it? ]

Working around weird paths which made imports impossible was easy, like with mod_wsgi and apache, so I did it very quickly. "script" attribute of triggers, that needs to be in main script file and has to be directly callable (object.method as a trigger won't work)? No problem, I wrote simple dispatcher and TriggerRegistry class which maps triggers to any callable. world.Note accepting only strings? It's even easier, just wrap it with some printer object. And so on...

Now I have seven script files, still long way to go - and for few weeks I haven't play my MUD. But hey, programming is better than playing, right? ;)

Also, I see you're no python fan and I don't want to convince you to become one right now. I just want to tell you that - while for ordinary users it's just fine - scripting support is quite restrictive for programmers (which hearing words "global variable" scream in horror, for example), and I guess any Ruby or even Perl developer scripting for MC would agree with me. I understand that it's WSH fault (I have to read more about it, I know almost nothing now), but I know for sure, that there are better ways for embedding scripting languages.

[Wow, I missed one thing - MUSHClient source is now open! Sorry, last time I checked (few years ago...) it wasn't.]
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #8 on Wed 14 Jul 2010 09:44 AM (UTC)

Amended on Wed 14 Jul 2010 09:46 AM (UTC) by Twisol

Message
CJI said:
I just want to tell you that - while for ordinary users it's just fine - scripting support is quite restrictive for programmers (which hearing words "global variable" scream in horror, for example), and I guess any Ruby or even Perl developer scripting for MC would agree with me. I understand that it's WSH fault (I have to read more about it, I know almost nothing now), but I know for sure, that there are better ways for embedding scripting languages.


It's almost definitely the fault of WSH. Lua is embedded directly, without using WSH, and is much much easier to use. (Yes, I've tried others with MC, specifically Ruby.)

As a side-note, I can't begin to tell you how hard I'm facepalming right now. XD Do you know how many people protested at the very idea of limiting MUSHclient scripting to one embedded language? Managing multiple scripting interpreters without WSH is almost certainly no easy task. The best design I personally have come up with - just as a mental exercise, nothing concrete - would require someone to create a new DLL with the scripting language embedded within, including glue routines that access a common API within MUSHclient. And do you know, that's exactly how WSH works?

So really, we can use either WSH or just one language. (Correct me if I'm wrong, Nick.) And the "one language" would almost certainly be Lua. Lua is extremely suitable for embedding within an application, with the major benefit that it's extremely easy to sandbox. (God, try doing THAT in Ruby. I love the language to death, but it is just not made for sandboxing.)

On a less... passionate note (sorry!), I'm not really a language fanboy. I treat my languages as tools, and I try to use the best tool for the job whenever possible. I don't know anything about you, so don't take this personally... it's late, and things might not be coming out right. (Wouldn't be the first time.) But it seems to me like, when you only have a hammer, everything starts to look like a nail. In one sense, WSH could actually be a detriment.

Man... I need to get some sleep. Again, I'm sorry if anything came out wrong, trust me when I say I'm not trying to start a fight. I just saw what you said above (that I quoted), and stuff just started pouring out. XD

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by CJI   Poland  (7 posts)  Bio
Date Reply #9 on Wed 14 Jul 2010 10:36 AM (UTC)
Message
Twisol said:

The best design I personally have come up with - just as a mental exercise, nothing concrete - would require someone to create a new DLL with the scripting language embedded within, including glue routines that access a common API within MUSHclient.


Yes, I realised that much - and I was suspecting that WSH does something like that, too. I just thought that "creating a new DLL with the scripting language embedded within" is quite an easy task - I have some experience in directly embedding Python and it was simple and fun for the most part.

But, as I said, I have no knowledge of WSH at all and I don't want to criticize MUSHClient design. I see that using WSH is the most comfortable option which demands the least work and I agree that it is enough for almost every scripting task. This threading thing is just one issue that seems to be impossible - and it's certainly not enough to justify major rewrite of scripting in MUSHClient. I was just curious - why it works that way and if there is something that could be done to correct it without big changes, that's all.

Twisol said:

God, try doing THAT in Ruby. I love the language to death, but it is just not made for sandboxing.


I had to think for a while. At first I was like "why is sandboxing even necessary?" because I never ran any script not written by me. And then I realised that it wouldn't be nice to run some downloaded plugin and have all my files deleted, for example.

Twisol said:

On a less... passionate note (sorry!), I'm not really a language fanboy. I treat my languages as tools, and I try to use the best tool for the job whenever possible. I don't know anything about you, so don't take this personally... it's late, and things might not be coming out right. (Wouldn't be the first time.) But it seems to me like, when you only have a hammer, everything starts to look like a nail. In one sense, WSH could actually be a detriment.


I had to look up 'detriment' in dictionary, and that's only thing that irritated me (joking) in this piece of text ;)

It's certainly true that there are different tools for different problems, I accept that. That said - I use Python mainly to write standalone apps or with web development frameworks (Django, Plone) and I'm just not used to working under restrictions found in MUSHClient.

They are workable around, of course, and I'm doing it right now. But I'm a little disturbed now - I mean your suggestion that 'everything starts to look like a nail'. I'm not offended or anything, but I started to wonder whether my goal is the right thing to do in scripting environment of MUSHClient. I'll write separate post (and topic) explaining what I want to do and I hope that you'll comment there, ok?

Twisol said:

Man... I need to get some sleep. Again, I'm sorry if anything came out wrong, trust me when I say I'm not trying to start a fight. I just saw what you said above (that I quoted), and stuff just started pouring out. XD


No problem, thanks for replying ang get some sleep :) And it's actually noon for me ;)
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #10 on Wed 14 Jul 2010 10:52 AM (UTC)

Amended on Wed 14 Jul 2010 10:53 AM (UTC) by Nick Gammon

Message
CJI said:

But that's not the point - various techniques, like coroutines or deferreds in Twisted are nice, of course, but are NOT threads. You can not use ANY blocking operation in coroutines, ...


Hmmmm. Before I answer in more detail (it is getting late here) I just want to say that a while back I thought threads were some sort of magical solution to all sorts of problems (eg. blocking operations). I gradually became more disillusioned with them, partly because of issues with threads needing to have thread-safe locks before accessing variables which might be changed by different threads. More recently I found this:

http://www.sqlite.org/faq.html#q6

Quote:

(6) Is SQLite threadsafe?

Threads are evil. Avoid them.


That link leads here:

http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf

And to quote from that document:

Quote:

They make programs absurdly nondeterministic, and rely on programming style to constrain that nondeterminism to achieve deterministic aims.


So the gist of my response is to query whether, in saying MUSHclient and Python and threads don't work together that well, is that is this really a huge problem in MUSHclient, or perhaps ... perhaps ... you should revisit using threads? :-)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by CJI   Poland  (7 posts)  Bio
Date Reply #11 on Wed 14 Jul 2010 11:21 AM (UTC)

Amended on Wed 14 Jul 2010 11:31 AM (UTC) by CJI

Message
Quote:

(6) Is SQLite threadsafe?
Threads are evil. Avoid them.


:D Good point.

Now, where have I seen thread used... Where could it be... Oh, yes, I remember:


// ------------------- script file change monitoring thread -------------------------

void CMUSHclientDoc::ThreadFunc(LPVOID pParam)
{
// ...

// Create script source file monitoring thread
//
void CMUSHclientDoc::CreateMonitoringThread()
{
  KillThread (m_pThread, m_eventScriptFileChanged);

	CThreadData*	pData = new CThreadData;
	pData->m_strFilename = new char [m_strScriptFilename.GetLength () + 1];
  strcpy (pData->m_strFilename, m_strScriptFilename);
	pData->m_hWnd = Frame.GetSafeHwnd ();
	pData->m_hEvent = m_eventScriptFileChanged;
  pData->m_pDoc = (DWORD) this;
	m_eventScriptFileChanged.ResetEvent();

	m_pThread = (HANDLE) _beginthread (ThreadFunc, 0, pData);
  SetThreadPriority (m_pThread, THREAD_PRIORITY_IDLE);

	// Thread will delete data object
}


:P

It's not that I have to use threads at all costs. They just have their place in programming since long ago, that's all.

And to justify myself - I wanted to do in Python same thing you did with CreateMonitoringThread - check whether source code of some module (other than main script file, which above routine takes care of) has changed and automatically restart script engine then. I would do it with timer from the start, but I found this nice (threaded) routine: http://code.djangoproject.com/browser/django/trunk/django/utils/autoreload.py and tried to use it. That was bad idea... Now I use it with timer and it works, so it's not an issue.
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #12 on Wed 14 Jul 2010 05:13 PM (UTC)
Message
Refreshed and awake(-ish) now!

CJI said:
Yes, I realised that much - and I was suspecting that WSH does something like that, too. I just thought that "creating a new DLL with the scripting language embedded within" is quite an easy task - I have some experience in directly embedding Python and it was simple and fun for the most part.

But, as I said, I have no knowledge of WSH at all and I don't want to criticize MUSHClient design. I see that using WSH is the most comfortable option which demands the least work and I agree that it is enough for almost every scripting task. This threading thing is just one issue that seems to be impossible - and it's certainly not enough to justify major rewrite of scripting in MUSHClient. I was just curious - why it works that way and if there is something that could be done to correct it without big changes, that's all.


*nod* I understand. Yes, generally embedding a language is fairly easy, I've done it myself with Lua. The problem is that someone needs to maintain these new DLLs, and provide the glue routines that translate the generic MUSH calls into language-specific operations, and vice versa. And you rely solely on that person to ensure that your scripting experience isn't lamer than WSH. And of course, someone has to design the generic API that each DLL would use. Everything just adds up to a subpar experience in my opinon. It's much easier to focus on one language, and make it shine.

CJI said:
I had to think for a while. At first I was like "why is sandboxing even necessary?" because I never ran any script not written by me. And then I realised that it wouldn't be nice to run some downloaded plugin and have all my files de-leted, for example.

Exactly. And there's almost no sandboxing with the WSH languages, and I honestly don't know where to even begin adding it with a custom WSH-like design. Most of these languages come with extensive standard libraries already. With Lua, it's a downright breeze! You simply disable the standard libraries that pose a risk to your application, and provide your own API functions that expose the specific functionality that scripters will use to interact with the client.

CJI said:
I had to look up 'detriment' in dictionary, and that's only thing that irritated me (joking) in this piece of text ;)

It's certainly true that there are different tools for different problems, I accept that. That said - I use Python mainly to write standalone apps or with web development frameworks (Django, Plone) and I'm just not used to working under restrictions found in MUSHClient.

They are workable around, of course, and I'm doing it right now. But I'm a little disturbed now - I mean your suggestion that 'everything starts to look like a nail'. I'm not offended or anything, but I started to wonder whether my goal is the right thing to do in scripting environment of MUSHClient. I'll write separate post (and topic) explaining what I want to do and I hope that you'll comment there, ok?


That's exactly my point. :) Python and the like are really good standalone languages, and they're very good when that's what you're writing. But I'm not sure it's the right tool when you want an embedded language. And just to clarify my "WSH is a detriment" statement, WSH makes everything look like nails, by providing a suite of languages but exposing exactly the same things to them. It puts the choice of language almost entirely down to taste!

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #13 on Wed 14 Jul 2010 05:18 PM (UTC)
Message
Twisol said:
Python and the like are really good standalone languages, and they're very good when that's what you're writing. But I'm not sure it's the right tool when you want an embedded language.

Eh, Python isn't nearly as bad to embed as some of the other languages. And many applications (e.g., EvE Online) have very, very successfully embedded Python.

The Python API isn't as nice as Lua's (it's more complicated, really) but it is far, far nicer than, say, Perl.

In principle somebody could do a proper embedding of Python as Nick did for Lua, if you felt like spending the time on it. I think the words about subpar experiences are slightly exaggerated when it comes to this, but you do need an advocate of some sort willing to stand behind it and do the work.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #14 on Wed 14 Jul 2010 05:19 PM (UTC)
Message
CJI said:
And to justify myself - I wanted to do in Python same thing you did with CreateMonitoringThread - check whether source code of some module (other than main script file, which above routine takes care of) has changed and automatically restart script engine then. I would do it with timer from the start, but I found this nice (threaded) routine: http://code.djangoproject.com/browser/django/trunk/django/utils/autoreload.py and tried to use it. That was bad idea... Now I use it with timer and it works, so it's not an issue.


Hmm... You can use UdpListen() in MUSHclient to set up a UDP port to listen on, and run a standalone Python program that uses your thread to watch the file. Then when it sees a change, it can notify your MUSHclient script via the UDP port.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


80,024 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.