mIRC Home    About    Download    Register    News    Help

Print Thread
Page 1 of 2 1 2
#223435 24/07/10 01:52 PM
Joined: Nov 2008
Posts: 3
V
Self-satisified door
OP Offline
Self-satisified door
V
Joined: Nov 2008
Posts: 3
Where i can get free channel protecting bots for my new channel

Vickygautam #223437 24/07/10 02:10 PM
Joined: Nov 2009
Posts: 81
V
Babel fish
Offline
Babel fish
V
Joined: Nov 2009
Posts: 81
hawkee.com
mircscripts.org

Voglea #224486 12/08/10 01:11 AM
Joined: Aug 2010
Posts: 19
M
Pikka bird
Offline
Pikka bird
M
Joined: Aug 2010
Posts: 19
You can also get eggdrop is more Protect...


~Manit~
Manit #224502 12/08/10 09:06 AM
Joined: Feb 2003
Posts: 3,432
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Feb 2003
Posts: 3,432
Originally Posted By: Manit
You can also get eggdrop is more Protect...

More protection yes, but free no, not if you don't have your own *nix computer running.. smile

But you can try windrop and see if thats what u looking for..


if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
sparta #224505 12/08/10 11:35 AM
Joined: Jan 2009
Posts: 116
Vogon poet
Offline
Vogon poet
Joined: Jan 2009
Posts: 116
Eggdrop is also, in my opinion, a bit... crap. It probably could be good, but it seems that most people fail to properly configure them, turning them into more of an annoyance than help ;_)

I should probably eventually release my MSL bot framework, although it's not really über-newbie-friendly..


http://zowb.net

/server -m irc.p2p-network.net -j #zomgwtfbbq
(ssl on port 6697 and 7000)
Knoeki #224512 12/08/10 01:15 PM
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
For a single channel it should be sufficient, but for bots on a *large* scale, a notable downside of mIRC/MSL is it's single-theadedness.
Imho truly "reliable" protection requires a dedicated system in any way (be it nix or win), and if the IRC network provides services and modes (like UnrealIRCs +f), they're among the most stable "free channel protecting bots" you can get.

Horstl #224520 12/08/10 06:15 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
What does "single-threadedness" have to do with anything? The bottleneck is NOT your CPU, it's the connection.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #224521 12/08/10 06:19 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
That statement implies you know what the bot does.

A bot that reads from a file would benefit quite a lot from multithreading, as would one that does something with COM objects.

hixxy #224533 12/08/10 10:29 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
That statement implies that you have no idea how multithreading can improve performance. A badly designed single-threaded program is going to be slower than a badly designed multi-threaded one, sure, but no robust bot designed for high traffic would "read from a file" at every request-- it would cache in memory, index lookups, or implement a whole host of other performance optimizations before wasting time implementing multi-threaded code.

Making a blanket statement that mIRC is bad because it is single-threaded is really uninformed. Multithreaded applications don't magically perform better, it depends very heavily on the use case, and performance does not increase throughout the application (it's usually limited to a very small portion of the runtime). Most of the time, the conclusion can only be drawn by actual benchmarks. That said, given the bottleneck of a TCP connection, the relatively low amount of data flowing through an IRC socket (on the order of ~100kb/s maximum), and the other things you can do to make a script run faster (caching, indexing, DLLs), I really doubt many scripts are really in need of multi-threading.

It should also be pointed out that eggdrops aren't multi-threaded as far as I know, so claiming that eggdrops are better because "mIRC is single-threaded" is inherently bogus. In fact, Tcl, the scripting language that eggdrop uses, is known for recommending scripters use the single-threaded event loop rather than threads, whenever possible.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #224554 13/08/10 01:29 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
Even with caching, a cache is only suitable until the file changes, at which point it would need to be re-cached. If a file is constantly changing then there is little benefit to caching.

Just as a badly designed multi-threaded program would run more efficiently than a badly designed single-threaded program, a well designed multi-threaded program would run more efficiently than a well designed single-threaded program (especially with dual, tri, quad, hexacore computers being the standard these days). It stands to reason that a bot that can perform two tasks at once will perform faster than a bot that can perform only one task at a time, no matter how well coded the single task one is.

Imagine a trivia bot running in a large channel that has !commands for top 10 leaderboards and whatnot. Now assume that the cache of this leaderboard is not up to date and the bot's stats file needs to be reprocessed. Let's assume it has stats for 10,000 players and takes a while to process. Whilst somebody is asking for the top 10, another player wants a hint for the current round. The player who wants the hint would have to wait until the bot has done processing the file before they get their hint, at which point the player might run out of time for that round. That's just one example.

As for your second and third paragraphs, I don't think they were meant for me as I never said mIRC was bad nor did I mention eggdrops :P

hixxy #224572 14/08/10 02:21 AM
Joined: Jan 2009
Posts: 116
Vogon poet
Offline
Vogon poet
Joined: Jan 2009
Posts: 116
There's mThreads.dll, which allows you to achieve threading with mIRC. I can't vow for it's stability though, as I never used it.

My bot is mIRC based. It's in 51 channels across 8 networks, it runs on a 434MHz celeron with 384MB of RAM, and it works damn near flawless other than the CPU being a slight issue with larger scripts.


http://zowb.net

/server -m irc.p2p-network.net -j #zomgwtfbbq
(ssl on port 6697 and 7000)
hixxy #224581 14/08/10 07:14 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Knoeki's reply basically summarizes my point.

Yes, a well designed multi-threaded app will be more efficient than a single threaded app. That's not the question. The question is whether that efficiency is necessary. Most of the time it's not. If you want to show that it is, benchmark it-- theory doesn't really help.

Your example has a few problems. First, this is not how you implement caching. If a cache was "out of date" (hard to happen, since you would cache on-write and on-read), you still wouldn't reprocess the full "file", you would just invalidate the cache and cache on the next read. We agreed that we'd be talking about "well designed" systems here-- therefore, you would never process the full "file" -- again, there's a good chance you're even using an indexed database here . In fact, 10,000 records is handled extremely easily with MySQL or SQLite; so easily that a dataset of this size is really considered "small". These databases can handle queries over millions of records in a few milliseconds.

More importantly, there are algorithms to keep track of the "top 10" users in real time with O(1) complexity. If we were specifically talking about your scenario of accessing the top 10, this would be as simple as updating the list of 10 users whenever a round ended (offloading the "heavy" data processing after a round and therefore not delaying requests to answer). It would be nothing more than /msg %nick %trivia.top10, and updating %trivia.top10 with 10 nicknames after the round.

But even if this was any arbitrary query over a dataset (which you could still optimize for in the same manner as above), and even if you decided to badly design your system to reparse the index *during* a round (which you wouldn't do), we're still talking about an unlikely situation. It's easier to avoid this than to add the multithreading complexity in handling all that locking. Writing mutlithreaded code is really hard, it adds a lot of weird edge cases and a whole set of new problems. For instance, let's say you had that multithreaded code and 2 people asked for the top 10 list at once? You'd have to make sure you put a mutex around your file reprocessing, otherwise you'd end up corrupting your cache. Do you really need to add all that complexity instead of just updating your top 10 cache between rounds?

Like I said, multithreaded code is not useless, but it should be taken on a case by case basis and should really be the last resort. And at the level of a scripting language, you rarely need the last resort.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #224649 15/08/10 07:52 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
How can you benchmark it? The benefit of multithreading is the ability to do more than one thing at a time is it not? Like the ability to update a progress bar in a dialog whilst in the middle of a while loop? Like the ability to be able to carry on using mIRC whilst it is in the middle of a huge $findfile() command?

The benefits of multi threading are so plainly obvious that I'm not sure benchmarks are actually necessary.

hixxy #224650 15/08/10 08:00 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
How? By timing the duration of an operation. Multi-threading has nothing to do with the ability to time code. Time still exists in a multi-threaded world.

Plainly obvious? Again, it sounds like you have little experience writing actual multi-threaded code. Slapping on a bunch of threads does not necessarily yield a significantly faster application. It depends heavily on *how* you use the threads, and *why*. The implementation might make it faster by 20%, or it might just make it faster by 1%, or maybe 0.005%. The latter two being insignificant values and probably not worth the effort, by the way. Heck, it might even be slower. Therefore, yes, benchmarks are necessary.

Frankly, anytime anyone says "benchmarks aren't necessary to prove X is faster than Y", there's something wrong with their argument. It would be similar to the fallacy of saying: "quicksort is obviously better than bubblesort because it's O(nlogn), I don't need to prove it with benchmarks".


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #224651 15/08/10 08:07 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
You're right, I have never written multithreaded code and am speaking as a user, not a programmer. I think the not locking up part is more important than the speed benefits. Being able to still browse the menus, options dialogs etc, whilst mIRC is performing a loop/findfile/other blocking command is very useful.

hixxy #224652 15/08/10 08:21 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
mThreads.dll, if it works correctly, should be able to do this. There are also some COM hacks to be able to run in a "thread" (similar to the "sleep" script floating around). You can also offload work to a separate process, depending on what you're doing. But I don't really think this has to do with the scripting engine anymore. The UI could perhaps be running in a separate thread from the script layer, that's a valid concern regarding overall UI responsiveness, but the script layer itself should still be single-threaded. The UI should not really have anything to do with the performance of a (dedicated) bot.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #224654 15/08/10 08:58 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
I still think that parts of the script engine should run in separate threads. mIRC being able to process events whilst it is running a lengthy while loop/$findfile command would be infinitely useful.

As I said though, I'm not a programmer (have dabbled but never went into anything as in-depth as threading) so I'm not sure how difficult this would be to implement or whether it's "safe" to do so.

hixxy #224656 15/08/10 09:37 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
It's not safe at all. It incurs a huge burden on the scripter. When you lose synchronous deterministic behaviour you gain the complexity of having to manually synchronize everything yourself. The beauty of mIRC is its simplicity.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #224662 15/08/10 10:50 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
I'm talking about mIRC doing this automatically and behind the scenes, not giving the scripter the ability to create and manipulate threads :P

Vickygautam #225229 28/08/10 09:01 PM
Joined: Jul 2006
Posts: 242
H
Fjord artisan
Offline
Fjord artisan
H
Joined: Jul 2006
Posts: 242
Seems to be lots of requests for this sort of thing. We used Pbot, and it sorted our server. http://mirc.net/projects.php?go=1218035463



Newbie
hixxy #225231 28/08/10 11:35 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
There's really no such thing as "behind the scenes" with threading. Once you add threads to your environment you need a way for the script to synchronize them, it's far too difficult if not impossible to do automatically, especially for a crude interpreter such as mIRC.

Consider a script that relies on the results of a $findfile for a subsequent event-- a setup that in your system would run on two separate threads:

Code:
on *:TEXT:!count *:#:set %total $findfile($1-, *, 0, 0)
on *:TEXT:!report:#:msg # %total


If a user types !count and !report immediately after, mIRC will still be in a $findfile loop on another thread when it returns the total value. It will therefore report a wrong or undefined value. It's impossible for mIRC to synchronize this automatically, because mIRC has no way of knowing what data is being shared across threads. Only the programmer can possibly know the answer to that (and often even the programmer doesn't know, hence the complexity involving threaded code). It is therefore necessary for the user to give the user a way to synchronize this code. Setting %total to $null is not sufficient, because there would still be a race condition that could lead to corruption or data, or worse, crashing of mIRC.

If every command mIRC ran was immutable and stateless, it would be feasible to run (almost) everything in a thread. It is of course impossible to guarantee this with mIRC's language, since data is neither immutable nor stateless.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #225388 01/09/10 01:19 PM
Joined: Aug 2010
Posts: 134
T
Vogon poet
Offline
Vogon poet
T
Joined: Aug 2010
Posts: 134
Reading this thread raised some questions for me. I can guess the answers to most of my own questions, but I would like to see them verified.

First, it's mentioned that mIRC script on default runs as a single thread. Does this also imply that if you run a mIRC bot on a Quadcore, it only uses at most a quarter of the processor's raw processing power?

Second, if you use external .dll files like mthreads.dll to create additional threads, would these threads also run on the same part of the processor, or would they be able to trigger other parts of the processor, causing a gain in speed on Dual- and Quadcores?

Third, does anyone have any experience with mthreads.dll? The documentation is very limited, though the accompanying mIRC code is clear enough. What about version compatibility?

Fourth, if you run separate threads, you of course have to make sure that you're not working with the same variables, since that would screw up your own data results. But what about addressing the same hash table. If I'm using a "$hget(MyTable, ValueA)" in one thread, and a "hadd MyTable ValueB 100" in a parallel thread, does a chance exist that while the $hget of the first thread is executing, the hadd of the second thread is being triggered?

Perhaps the chance of that would be kind of small, but possibly a more practical example: I'm running a bot that stores quite a bit of data in hash tables. To prevent the data from disappearing due to a power loss, I hsave all the hash tables every 10 minutes. This causes mIRC to "freeze" for a good 3-4 seconds every 10 minutes.

Now, if I would use mthreads.dll for saving the data, I shouldn't notice the "freeze" effect, correct? But could there be a problem if another script would be writing data to one of those hash files during that time? I wouldn't mind if that single entry wouldn't be stored (after all, it wouldn't be stored during serial processing), but could it corrupt the data being saved to the harddisk?


Learning something new every day.
argv0 #225447 02/09/10 05:10 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
In that case I would like to see $findfilecall() and $finddircall(), just like $dllcall() and $comcall() - there has been a relatively few number of bug reports related to these identifiers since their addition to the language and I haven't seen any hideous crash reports.

And perhaps a built-in method of doing what WhileFix.dll does, which I believe is a simple call of TranslateMessage() and DispatchMessage() if memory serves me correctly. This allows the UI to update and new input to be processed even whilst in the middle of a loop.

Thels #225470 03/09/10 03:42 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Originally Posted By: Thels
First, it's mentioned that mIRC script on default runs as a single thread. Does this also imply that if you run a mIRC bot on a Quadcore, it only uses at most a quarter of the processor's raw processing power?


Yes.

Originally Posted By: Thels
Second, if you use external .dll files like mthreads.dll to create additional threads, would these threads also run on the same part of the processor, or would they be able to trigger other parts of the processor, causing a gain in speed on Dual- and Quadcores?


Any threads spawned from a DLL would be eligible for scheduling on all 4 cores. So yes, you can get speed increase from using a dll-- HOWEVER,

This speed increase only applies to the processing done inside your dll (outside of mIRC). Once you start touching mIRC (SendMessage, etc.) you are thrown back into mIRC's single thread. You also have to take care, when using such a threaded DLL, to make sure that you properly synchronize threads. Manipulating mIRC in multiple threads (without proper locking) can easily cause mIRC to crash.

Originally Posted By: Thels
Third, does anyone have any experience with mthreads.dll? The documentation is very limited, though the accompanying mIRC code is clear enough. What about version compatibility?


I cannot answer this. I would guess that the dll is a very low level API over pthread or Windows' threading API, and you can probably find much more documentation on MSDN.

Originally Posted By: Thels
Fourth, if you run separate threads, you of course have to make sure that you're not working with the same variables, since that would screw up your own data results. But what about addressing the same hash table. If I'm using a "$hget(MyTable, ValueA)" in one thread, and a "hadd MyTable ValueB 100" in a parallel thread, does a chance exist that while the $hget of the first thread is executing, the hadd of the second thread is being triggered?


Again, it depends how you do it. You would need to create semaphores or mutexes around all of your data accesses, though. This means if your dll does nothing but interact with mIRC, you will basically see no speed increase, because you will constantly be locked in a single thread (you might even see a speed decrease from that). With SendMessage, your thread is going to block until mIRC returns the data anyway (see the remarks on SendMessage threading), so theres no synchronization needed there-- but of course there's no threading done there either (it's essentially going to lock you into one thread again).

Originally Posted By: Thels
Perhaps the chance of that would be kind of small, but possibly a more practical example: I'm running a bot that stores quite a bit of data in hash tables. To prevent the data from disappearing due to a power loss, I hsave all the hash tables every 10 minutes. This causes mIRC to "freeze" for a good 3-4 seconds every 10 minutes.

Now, if I would use mthreads.dll for saving the data, I shouldn't notice the "freeze" effect, correct? But could there be a problem if another script would be writing data to one of those hash files during that time? I wouldn't mind if that single entry wouldn't be stored (after all, it wouldn't be stored during serial processing), but could it corrupt the data being saved to the harddisk?


I don't know enough about mthreads.dll to comment. It looks like it just separates the script engine from the UI. mIRC will continue to look active but the script layer will be blocked. This may have unwanted consequences, though I'm not sure exactly what. I wouldn't recommend using it, in general.

If it's taking 3-4seconds to save, you've probably outgrown hash tables, or at least outgrown using a single hash table. As I mentioned earlier in the thread, you probably shouldn't be loading all of your data directly into memory if this is the case. You should consider using sqlite or some data store with the ability to index your data and optimize lookups without requiring everything in memory. This would also guarantee persistence, too (no 10 minute timer needed for saving data).

Alternatively you can use multiple hash tables-- one for persistent read-only data storing the bulk of the data but only saved on exit, and one hash table for new and modified entries that were added in your current session only. That table would be much smaller and would be the one that was saved every 5-10 minutes. When you close mIRC (or force a flush to disk) you would move the data from the "current session" table to your persistence table and store that.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
hixxy #225471 03/09/10 03:48 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Originally Posted By: hixxy
In that case I would like to see $findfilecall() and $finddircall(), just like $dllcall() and $comcall() - there has been a relatively few number of bug reports related to these identifiers since their addition to the language and I haven't seen any hideous crash reports.


$comcall and $dllcall are not (strictly) multi-threaded, which is likely why, if you were expecting to see thread related "hideous crash reports", you saw none. When they do involve threads, they're completely synchronized on mIRC's end, which isn't really the same issue at all. Functionally they are simply asynchronous callback functions that make use of the SINGLE THREADED event loop-- mIRC always responds in the same thread. There's no reason why mIRC can't do the same thing with $findfile, except that it will make lookups much slower-- not in terms of responsiveness, but in terms of time to complete a search.

Note that you can achieve the exact same effect by simply writing a /timer loop over $findfile(dir,*,%i)

Also, if you're really concerned with speed, you can also write your own DLL that does directory traversal with an asynchronous callback by just passing your directory and callback method to $dllcall


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #225472 03/09/10 07:06 AM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
It's not so much speed that's an issue, it's the fact that there's no way to avoid the synchronous method of these two identifiers at the moment (without using a messy hack like the timer method you suggested).

It's like how the while ($sockbr) sockread method in a single sockread is faster than using multiple asynchronous sockread events. People use the latter even though it's slower because mIRC can continue to do other things.

You didn't comment on my WhileFix.dll suggestion, do you think that would have any adverse effects?

argv0 #225480 03/09/10 09:02 AM
Joined: Aug 2010
Posts: 134
T
Vogon poet
Offline
Vogon poet
T
Joined: Aug 2010
Posts: 134
Thanks argv0, you've been a great help!

Originally Posted By: argv0
I cannot answer this. I would guess that the dll is a very low level API over pthread or Windows' threading API, and you can probably find much more documentation on MSDN.

I don't know enough about mthreads.dll to comment. It looks like it just separates the script engine from the UI. mIRC will continue to look active but the script layer will be blocked. This may have unwanted consequences, though I'm not sure exactly what. I wouldn't recommend using it, in general.


Actually, mthreads.dll is a dll specifically written for mIRC to allow multiple scripts to run next to each other. I doubt I'll find anything about a mIRC specific dll in the MSDN library. That or I totally mistook your advice.

Originally Posted By: argv0
If it's taking 3-4seconds to save, you've probably outgrown hash tables, or at least outgrown using a single hash table. As I mentioned earlier in the thread, you probably shouldn't be loading all of your data directly into memory if this is the case. You should consider using sqlite or some data store with the ability to index your data and optimize lookups without requiring everything in memory. This would also guarantee persistence, too (no 10 minute timer needed for saving data).

Alternatively you can use multiple hash tables-- one for persistent read-only data storing the bulk of the data but only saved on exit, and one hash table for new and modified entries that were added in your current session only. That table would be much smaller and would be the one that was saved every 5-10 minutes. When you close mIRC (or force a flush to disk) you would move the data from the "current session" table to your persistence table and store that.


I'm already using multiple hash tables, some read-only and some dynamic. The read-only hash tables aren't saved of course. As for the dynamic hash tables, one is over 12mb and will keep growing fast, while the others are under half an mb together. I can probably think of an alternative to the single one large hash table, just haven't come around doing it yet.

I'll leave mthreads.dll and sqlite for possible future plans. Lots of work left to do in the near future. All my calls from and sends to hash tables are aliases, so reworking, while it would be a large project, wouldn't require me to dig through the entire code.

Last edited by Thels; 03/09/10 09:07 AM.

Learning something new every day.
hixxy #225481 03/09/10 09:15 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Originally Posted By: hixxy
You didn't comment on my WhileFix.dll suggestion, do you think that would have any adverse effects?


Besides making the script slightly slower, not really. Event processing might occur out of order, but that's about it. WhileFix doesn't thread, it basically forces mIRC to process message events between each loop iteration (or whenever you call on the whilefix dll file). Technically you can use this inside your $findfile call:

Code:
alias whilefix { dll WhileFix.dll WhileFix . | $1 }
noop $findfile(dir,*,0,0,$whilefix(command here))


Perhaps mIRC could do with a /updateui command that would basically force a processing of the message loop (exactly what whilefix does) and people could just insert those into their long running tasks to make mIRC seem more active. That wouldn't be a bad idea at all.



- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Thels #225482 03/09/10 09:24 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Originally Posted By: Thels
Actually, mthreads.dll is a dll specifically written for mIRC to allow multiple scripts to run next to each other. I doubt I'll find anything about a mIRC specific dll in the MSDN library. That or I totally mistook your advice.


I know that it's meant for scripts, but it's likely just a thin wrapper over the CreateThread API call. Again, I'm not positive, but I'd bet that would be the case. If it is, MSDN has a LOT of resources on threaded programming in windows-- what can go wrong, what the architecture is like, what your expectations should be, etc. It's a good starting point regardless of mthreads' API.

Originally Posted By: Thels
I'm already using multiple hash tables, some read-only and some dynamic. The read-only hash tables aren't saved of course. As for the dynamic hash tables, one is over 12mb and will keep growing fast, while the others are under half an mb together. I can probably think of an alternative to the single one large hash table, just haven't come around doing it yet.


It's the 12mb hash file that you should be splitting up. I'm sure there's a way to further isolate the data you use. Even if you just split them up randomly (choose table based on $r(1,2)) you could schedule your saves independently and reduce the wait-time. For instance, you could have 2 timers saving each table, each running 5 minutes apart (but at 10 minute intervals)-- then, instead of 3-4 seconds of delay every 10 minutes you would only have 1-2 seconds of delay every 5 minutes. You could continue this division as necessary until you have negligible delays (1/4 second every 2 minutes).

It's not really a maintainable solution if your data is growing fast, but it's yet another optimization you can consider if you've tried other options.



- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #225484 03/09/10 09:31 AM
Joined: Aug 2010
Posts: 134
T
Vogon poet
Offline
Vogon poet
T
Joined: Aug 2010
Posts: 134
Originally Posted By: argv0
It's the 12mb hash file that you should be splitting up. I'm sure there's a way to further isolate the data you use. Even if you just split them up randomly (choose table based on $r(1,2)) you could schedule your saves independently and reduce the wait-time. For instance, you could have 2 timers saving each table, each running 5 minutes apart (but at 10 minute intervals)-- then, instead of 3-4 seconds of delay every 10 minutes you would only have 1-2 seconds of delay every 5 minutes. You could continue this division as necessary until you have negligible delays (1/4 second every 2 minutes).

It's not really a maintainable solution if your data is growing fast, but it's yet another optimization you can consider if you've tried other options.


I've thought about splitting it up, but since one table is the vast bulk of the data, that would be pointless. The data stored in that table is pretty much log data, for which retrieving speed is not an issue. Since the bot synchronizes channels on different networks and PMs with different people into one, mIRC's default logging system doesn't cut it.

I could just export the data to logfiles as I go, of course. Just gotta check in on how to do that in a nice matter. I don't want mIRC to access my HD a bunch of times every second, just to write one line.


Learning something new every day.
Thels #225486 03/09/10 10:36 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Then why not flush every 1min when the data is small enough to not delay mIRC? A write every 1min is pretty reasonable. You wouldn't even need to redesign anything, just bump your timer down to 1 minute and be sure to flush your table after the write.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #225489 03/09/10 12:33 PM
Joined: Aug 2010
Posts: 134
T
Vogon poet
Offline
Vogon poet
T
Joined: Aug 2010
Posts: 134
You mean with appending to the hash file? The only problem is that the order would be lost. Per "room", I store 1 hash entry containing the number of lines, and 2 hash entries per line, one storing the $gmt value at which the line was generated, and one storing the actual line.

Actually, ignore that. I could just keep the total number of lines in the hash file and keep on counting.

However, I should probably come around and change it so that I append the individual log entries to the end of the file(s), instead of just dumping the hash table into a file.

TBH, it's on my to-do list, and I should come around doing it one of these days. I just needed some quick and dirty way to start logging back when I started, and was planning on converting them to decent logs at a later time.

What's a proper way to write data to files, assuming I'll probably write more than one line at a time? Would the following example code be decent code, or would you recommend to do it different.

Code:
savelogs {
  .timersavelogs -io 1 60 savelogs

  ;Close the logfile if it is open for whatever reason.
  if $fopen(logfile) {
    fclose logfile
  }

  ;Check if the hash table exists.
  if $hget(Logs) {

    ;Create the logs directory if it doesn't exist.
    if !$isdir($qt($+($mircdir, logs\))) {
      mkdir $qt($+($mircdir, logs\))
    }

    ;Save the different log tables to variables, so they remain consistent as entries are deleted.
    var %logs $hfind(Logs, *_entries, 0, w)
    var %logcount 0
    while %logcount < %logs {
      var %logcount $calc(%logcount + 1)
      var %log [ $+ [ %logcount ] ] $left($hfind(Logs, *_entries, %logcount, w), -8)
    }

    ;Cycle through the different log tables.
    var %logcount 0
    while %logcount < %logs {
      var %logcount $calc(%logcount + 1)
      var %logname %log [ $+ [ %logcount ] ]

      ;Open the logfile. Check if this generates an error.
      fopen -n logfile $qt($+($mircdir, logs\, %logname, .log))
      if !$ferr {

        ;Cycle through the different log entries.
        var %entrycount 0
        while %entrycount < $hget(Logs, $+(%logname, _entries)) {
          var %entrycount $calc(%entrycount + 1)

          ;Write an entry to disk. If this causes an error, skip writing further entries for this logfile.
          if $hget(Logs, $+(%logname, _entry_, %entrycount))
          fwrite -n $asctime($hget(Logs, $+(%logname, _time_, %entrycount)), yyyy-mm-dd HH:nn:ss) $hget(Logs, $+(%logname, _entry_, %entrycount))
          if $ferr {
            goto :writefail
          }

          ;Remove the entry from memory.
          hdel Logs $+(%logname, _entry_, %entrycount)
          hdel Logs $+(%logname, _time_, %entrycount)
        }

        ;Remove the log table from memory.
        hdel Logs $+(%logname, _entries)
        :writefail
      }

      ;Close the file.
      if $fopen(logfile) {
        fclose logfile
      }
    }
  }
}


Would savebuf be a faster alternative, if I would display the logs in a @window, instead of writing them to a hash file? If so, is there a way to "mark" until where the window was saved during the last time, or would I have to use a counter per window?

Last edited by Thels; 03/09/10 12:33 PM.

Learning something new every day.
argv0 #225499 03/09/10 05:01 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
I would love to see an /updateui. Most complaints about mIRC being single threaded seem to be related to UI freezes etc.

Whilst the script would definitely be slower, that could be mitigated by updating the UI after every N iterations, like this:

Code:
var %i = 1, %str = $str(a,4000)
while ($left(%str,%i)) {
  echo -a $v1
  inc %i
  if (%i // 10) updateui
}


Would definitely be handy to have smile

Thels #225573 05/09/10 06:50 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
All I can say is benchmark the alternatives if you want to optimize properly. Intuition is often wrong, and making "educational guesses" about implementation details (like for /savebuf, for instance) doesn't always work out properly.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Page 1 of 2 1 2

Link Copied to Clipboard