Jump to content

Fr0sT.Brutal

Members
  • Content Count

    2268
  • Joined

  • Last visited

  • Days Won

    46

Everything posted by Fr0sT.Brutal

  1. Fr0sT.Brutal

    New section for native apps

    Flutter is working on Dart, right? A language with unclear perspectives. Anyway, what about binary sizes?
  2. Fr0sT.Brutal

    Best practices for handling a Stalled thread

    In your case I see no problems. If you're closing your app, just terminate the stalled threads. From what you said, they only do reading so no junk files remain and all handles/memory/resources will be freed on app close. If you're not closing the app, let the thread do its job; just show some progress mark. Maybe even mention that long operation isn't your app's fault, like "Doing my best to reconstruct index of a broken, shitty-formatted file that you've feed to me" 😄
  3. That's why I mentioned that a list should be unsorted; anyway this algo isn't trivial indeed, it will only make sense if number of deleted items is very low while the list itself is very large (so assigning/copying the items to remain in list will take significant time). Otherwise "packing" of the list seems more efficient (just one loop, two indexes - current item and current item to remain, 0 reallocs, number of assignments = list.Count - N_DelItems).
  4. No, you don't understand 😉 I suggested to exchange them not move. Of course it only sounds simple, there will be many gotchas to avoid so if resources allow, copy is always the easiest option.
  5. It strongly depends on list size, number of items to delete and, of course, the <T> itself. If <T> is not a simple type, f.ex., a big record with lots of managed fields, assigning could take ages. However, on pretty large lists this could be the only acceptable option as internal array realloc would exhaust available memory.
  6. I can say for FB only but it's unable to automatically sort out two concurrent updates of a same record, even with proper parameters. It could ensure data consistency but when two parallel transactions with isolation level "SNAPSHOT" modify the same value, it will throw an error. Moreover, this is the only correct behavior. Without explicit record locking DB server couldn't foretell what records you will touch and it ensures every transaction gets its own version of data. So if cnt is initially 0, Tx1 sets cnt=cnt+1 (effectively 1), Tx2 sets cnt=cnt+1 (effectively 1) as well, Tx1 commits, Tx2 commits too - what value cnt should have? Rather than losing a modification, it is safer for DS server to throw an error on Tx2's commit; moreover it postpones Tx2's update until Tx1 commits and only then throws. So user has to handle this situation manually anyway. DB server helps, but won't do all the work. Test case: two isql's, any database 1. isql#1 connect "fbtest" user SYSDBA password masterkey; SET TRANSACTION WAIT SNAPSHOT; 2. isql#2 - the same 3. isql#1 update some_table set some_field=some_field+1; 4. isql#2 - the same. Update hangs 5. isql#1 commit; 6. isql#2 - Statement failed, SQLSTATE = 40001 deadlock -update conflicts with concurrent update -concurrent transaction number is ####
  7. If the list is not sorted, probably the fastest option is to move items to be deleted to the end of the list by exchanging and then trim the list. This way only one memory reallocation happens. Depending on list length and available memory size, maybe creating a new list and copying only needed items to it would be quicker. Anyway, you really should benchmark this action first
  8. This task is pretty usual, it is called "aggregates". Keeping amount of goods in a warehouse is another example. There are two options for doing this right: - Locking. A transaction should lock the counter, update it and unlock. Other transactions must wait for it. This could be done artificially with generators serving like flags (GEN_ID(1) - counter is locked, GEN_ID(-1) - counter is unlocked) but it would require other transactions to loop until they get a lock; or it could be done with waiting transactions and SELECT FOR UPDATE. - Gathering aggregates. You just log all your events and calculate counter as SELECT COUNT(*) FROM T_VIEWS WHERE GAL_ID = :galID; of course the table can grow larger quickly so you also have to group all events happened before some moment and move the counters to an "archive" table, deleting the counted records from current table. This grouping must be done by a maintenance connection, not by a user, probably launched with scheduler. So you'll have the final result as PastCount = SELECT VIEW_COUNT FROM T_PAST_VIEWS WHERE GAL_ID = :galID; CurrCount = SELECT COUNT(*) FROM T_CURR_VIEWS WHERE GAL_ID = :galID; TotalCount = PastCount+CurrCount
  9. Hmm, very non-logical then. A really bad behavior encapsulation, IMHO.
  10. Fr0sT.Brutal

    Blogged : Introducing DPM - a Package Manager for Delphi

    Yeah, one copy located in DPM cache. So this approach won't benefit neither from IDE-global layout (i.e. configured via Settings>Library path) (a library is accessible to all projects without any modifications to the projects themselves) nor from project-local layout (a project is stand-alone and consistent, could be easily imported/backed up). By packing the project I mean something like Node's "npm pack" - creating a developer's package (archive) from a project folder. With all the above, I guess this feature becomes more necessary. (Just my 2 Bitcoin cents :D )
  11. NonBlocking AFAIK uses more threads under-the-hood so it just would add more hassle. And disconnecting a connection is senseless, it's not much different from creating/destroying a connection object every time. The idea of connection pool is to have several alive connections to DB and use them in threads. A connection object shouldn't be used by more than one thread at the same time but when a thread finishes its query, it returns a connection to pool.
  12. Fr0sT.Brutal

    Blogged : Introducing DPM - a Package Manager for Delphi

    Hmm, so, if I understood correctly, all packages installed by DPM will be global in fact. Then, I guess, packing the whole project would be a necessary feature
  13. Fr0sT.Brutal

    Blogged : Introducing DPM - a Package Manager for Delphi

    OTOH, I think we all have several active projects with full set of tests/CI/auto deployment/doc system etc and much, much more little projects for which using a completely individual set of libraries is overhead. Having 100 copies of JCL only because all 100 projects use a couple of its functions? I don't think it's a good idea
  14. Fr0sT.Brutal

    Closing an external App.

    Processes are the right way here. Listing all running processes, you can check their parent process and thus easily find all of them being spawned by your process. Of course you can traverse all the call chain to find processes being spawned by processes being spawned by processes being spawned by your process 🙂
  15. I prefer overloaded methods, but only for cases of 1) the same set of parameters differing only in types (good example is IfThen) 2) several parameter sets (2-3) Dozens of methods significantly differing in param sets are usually hard to understand. Quite often I add an overload to utilize a default parameter of a type that Delphi doesn't allow to set in code, like record, object or array (like Error(Msg) and Error(MsgFmt, [values])).
  16. Fr0sT.Brutal

    Blogged : Introducing DPM - a Package Manager for Delphi

    Looks very promising! Haven't examined this PM yet but definitely will give it a try. Quick notes on what I'd like to see in PM (probably they're implemented already): - Option to choose global (configurable path that will be added to IDE Library path) or local (inside the project folder, within configurable subfolder, path will be added to project Search path) installation - Packing the whole project with deps, with choice whether include global deps or not - Some kind of Delphinus support, maybe just a config converter from Delphinus to DPM - Installing from an archive from Internet, this way GitHub repos could be used as well. Installer should check archive's Last-Modified and don't download it if it wasn't changed
  17. Fr0sT.Brutal

    SChannel TLS - perform TLS communication with WinAPI

    Fixed plenty issues and added some helpers to circumvent SChannel bug. ICS socket handles it internally and transparently.
  18. Sure but that's not a big problem. Not necessary to call it too frequently, and after the long operation one can cleanup the queue manually. Or simply disable the main window and let these postponed messages go to NUL. However, I like Anders ' solution
  19. Fr0sT.Brutal

    [legal] Need help with Packet Sniffer in Delphi

    Well, I've heard of really powerful sniffer solutions available (WireShark is #1) and they probably allow user scripting. Besides that, if you need to modify traffic as well, maybe it's easier to write a proxy.
  20. Effectively not the same 😛 PeekMessage with NOREMOVE just "pings" the message queue telling OS the app is not frozen but without consuming/executing the messages so it seems to me absolutely safe and side effect-free (oppositely to PrMsgs that, without additional GUI actions, could allow such things as pushing Launch button again while the loop is already running, closing a form which is expected to receive results and even closing the app itself).
  21. Fr0sT.Brutal

    Combining several applications into one

    The easiest way to rename form DFM/PAS files is using IDE's "Save As" action, and renaming the form itself is best with changing the name of the form component from designer.
  22. Fr0sT.Brutal

    Combining several applications into one

    Ok, now it's more clear. I see no reasons why it shouldn't work if you'll have one DPR and thousands of forms. Just rename them in namespace manner and use in umbrella DPR, no auto-create is needed. Just do Application.CreateForm in your umbrella main form's menu onClick handlers. However, you'll have to ensure your under-umbrella apps contain nothing in their DPR but default App.Init/CreateForm/Run.
  23. Fr0sT.Brutal

    Combining several applications into one

    What's the problem, in brief? I also have FormMain.pas with TFrmMain in every of my VCL projects. Still can't get why you want to add the project name to the form name. But if you really want it, consider "namespace"-like manner - MyCoolProject.FormMain.pas
  24. Fr0sT.Brutal

    Using Expressions in the Group By Clause in Interbase

    I can't believe it took a decade for them to implement SELECT FROM SELECT
×