Wednesday, November 18, 2015

Connect Your Applications with REST – Links

The materials for my “Connect your applications with REST” workshop are now available online (in Slovenian language).

Below you can find all the interesting DELPHI- and REST-related links I have collected during the preparation of this workshop.

Thursday, November 12, 2015

Connect Your Applications with REST

Next Wednesday (18th) I’ll be holding a presentation about all things RESTish in Delphi. We’ll start with basics and then move to DataSnap, REST Client Library, REST Debugger, BaaS and more!
As usual, I’ll be presenting in Slovenian language.
Register here!

Sunday, October 18, 2015

Simplify Parallel Programming with Patterns

My CodeRage X session on parallel programming with patterns is now available on YouTube.

You can also download the slides (pps, pdf) and code.

Friday, October 16, 2015

Recording Webinars – My Workflow

Each time I have to record a webinar, I have trouble remembering how exactly did I do it last time, so I decided to document my workflow. Maybe this will help somebody else besides me …

If you have any ideas on how to improve my workflow or if you have a different way of solving same problems, then please post it in the comment section. Thanks!

[v 1.01: Added screenshots of CamStudio and Filmora settings and few words on Audacity settings.]
[v 1.02: Added appendix A with some time&space information.]

Updating a Progress Bar From a Parallel For Loop (Plus Two Bonuses)

During the Q&A part of my Simplify Parallel Programming with Patterns presentation on CodeRage X, I’ve promised the listeners to publish a demo for updating a progress bar from a parallel for loop.

In this article I’ll try to explain few different approaches that all solve this problem. I’ve also put together a demo project which demonstrates all techniques.

Thursday, September 24, 2015

Links for 10 Seattle Presentation in Ljubljana

Firstly, thanks to everybody who visited my RAD Studio 10 Seattle presentation! I’m sorry I had to improvise because of bad video drivers, but on the other hand RAD Studio performed great!

2015-09-24 09.16.20

Secondly, here is a bunch of links I’ve promised.

OmniThreadLibrary Spotlight now On-line

My short spotlight presentation about high-level OmniThreadLibrary patterns is now available on YouTube.

Wednesday, September 23, 2015

Conditional Compilation with Features

EDIT: Make sure you read this post to the very end!

Are you developing a code that must work in different Delphi versions? Are you sick of writing code like

{$IF CompilerVersion >= 22}
class function Mapper<T1,T2>:
IMapper<T1,T2>;
{$ENDIF}

as you a) never know when some feature was introduced into Delphi and b) constantly wonder which version of Delphi has CompilerVersion equal to 22?


Then maybe you could use this simple include file.


Wednesday, September 16, 2015

Learn All About RAD Studio 10 “Seattle” in Ljubljana

Next Thursday (24th) I’ll be presenting new RAD Studio 10 Seattle in Ljubljana. This is announcement for Slovenian readers.

Naslednji četrtek (24.) se mi pridružite v kristalni palači na predstavitvi novega RAD Studia 10 Seattle, ki je po mnenju mnogih (in tudi mojem), ena boljših različic tega programskega orodja v zadnjih letih.

Predstavil vam bom izboljšano podporo za Windows 10 (v VCL in FMX), nove vizualne gradnike, izboljšave v IDE, novo podporo za mobilna okolja (razhroščevanje iOS 64-bit programov, pisanje sistemskih storitev za Android), novosti in izboljšave v sistemskih knjižnicah RTL, pa tudi novosti v prevajalnikih za C++ in še marsikaj.

Več podatkov o dogodku najdete tu.

Monday, September 07, 2015

OmniThreadLibrary 3.05

Hear, hear, OmniThreadLibrary 3.05 has just been released!

What’s new? Not much.

  • Added Delphi 10 Seattle packages and projects. OmniThreadLibrary now supports Delphis from 2007 to 10 Seattle.
  • Setting IOmniThreadPool.MinWorkers property will start up idle worker threads if total number of threads managed by the thread pool is lower than the new value.

There were, however, many quite important bug fixes. You are strongly advised to update to this version!

Monday, August 31, 2015

OmniThreadLibrary on Delphinus

OmniThreadLibrary now supports the Delphinus package installer. If you are using Delphi XE or newer, you can install Delphinus, select OmniThreadLibrary, and click Install. Delphinus will do the same steps GetIt does: download OTL, recompile and install package, and add proper paths to the search and browsing path. Source will be installed to c:\Users\Public\Documents\Embarcadero\Studio\<release>\Comps\.

image

Friday, August 28, 2015

Spotlight on OmniThreadLibrary

If you are not using OmniThreadLibrary yet, or if you are only using its low-level parts (CreateTask and company), I’m kindly inviting you to a 20-minute presentation “Simple Parallel Programming with Patterns and OmniThreadLibrary”, which will be transmitted as a part of the Embarcadero Technology Partner Spotlights series on September 3rd.

There are three timeslots to chose from so I’m sure everybody can find a suitable time. After the first two presentations I’ll be handling Questions and Answers and Jim McKeeth has kindly offered to do the job for the third presentation as it will be around 02.25 AM here when it is finished.

If you want to see something interesting and new, register here!

[Slides, code, and video will be available on my blog after the presentation.]

Thursday, August 27, 2015

OmniThreadLibrary 3.04b on XE8

Just a quick note – OmniThreadLibrary 3.04b is now available on XE8 via GetIt.

Thursday, August 20, 2015

Book Update: Miscellaneous

I have updated the Parallel Programming with OmniThreadLibrary book with the Miscellaneous chapter. The book is now almost complete!

Changelog:

  • Documented TOmniMessageQueue.
  • Documented TOmniTwoWayChannel.
  • Documented TOmniValueContainer.
  • Documented TOmniCounter.
  • Documented TGp4AlignedInt and TGp8AlignedInt.
  • Documented TOmniRecordWrapper.
  • Documented IOmniAutoDestroyObject.
  • Documented IOmniEnvironment.
  • Documented examples.

Sunday, August 02, 2015

Setting Up a Parallel Build System

OmniThreadLibrary now supports 11 different Delphi versions (2007, 2009, 2010, XE, XE2, XE3, XE4, XE5, XE6, XE7, XE8), some with very special requirements about the supported pascal syntax (2007 and 2009 clearly standing out in that regard) so it takes quite some time to test the compilation of all demos and run unit tests on all supported editions. (And this time will only increase with the addition of support for mobile platforms and OS X. Not that I’m complaining. Sean is doing a terrific job there!)

It does not help that I don’t have all those Delphis installed on my computer. Most of them are only installed in a VM. And it takes a looooong time to start up a VM, run tests, power it down, start up next VM, and so on. And when I fix something, I have to retest it all ….

This kind of testing hurts. So in the manner of the Continuous Integration mantra, I decided to do it more often.

Wednesday, July 29, 2015

Double Bill: OmniThreadLibrary 3.04b & a Book Update

I have just updated OmniThreadLibrary to version 3.04b. This is kinda important update as I somehow messed the 3.04a release which did not include support for more than 60 concurrent tasks that was added in version 3.04. This important feature is now back and I’ve added few other small improvements.

Changelog for this release:

  • Reimplemented support for TWaitFor in the TOmniTaskControl which was removed from the code in release 3.04a by mistake.
  • Implemented TOmniSingleThreadUseChecker, a record which checks that the owner is only used from one thread.
  • TOmniCommunicationEndpoint.ReceiveWait and .SendWait are now fully thread-safe and support multiple consumers (former) and multiple producers (latter).

Version 3.04b can be downloaded here. Alternatively, you can check out this release or update to the trunk.

I have also released a new version of “the book” which is now 239 pages long! Following sections were added/updated:

  • Documented TOmniValue.
  • Documented TWaitFor.
  • Documented TOmniLockManager.
  • Documented TOmniSingleThreadUseChecker.
  • Adapted Communication Subsystem documentation.

Sunday, July 12, 2015

OmniThreadLibrary Book Update

After a (much too) long time, I have (finally) found some time to work on my book “Parallel Programming with OmniThreadLibrary”. For starters, I have updated existing content so that the current version (3.04) is properly documented. The following topics were added/updated:

  • Documented Parallel.For.
  • Documented Parallel.Map.
  • Documented TOmniBlockCollection.ToArray<T>.
  • Added longer example for Parallel.For.
  • Documented IOmniTaskConfig.SetPriority and .ThreadPool.
  • Documented Parallel.Pipeline.PipelineStage[] property.
  • Documented new demos.
  • Documented other changes and additions.
  • Updated hyperlinks.

Update is free (as it always was and as it will always be) for all owners of the book. You probably already received an email with details. If not, you should just go to LeanPub and download the new version.

You can buy the book (and with that support the OmniThreadLibrary development) here.

GpSQLBuilder Improvements

Thanks to [leledumbo], GpSQLBuilder now works with the FPC pascal and supports the INSERT statement.

You can now write statements such as:

  query := CreateGpSQLBuilder
.Insert
.Into(DB_TEST)
.&Set(COL_1, [42])
.&Set(COL_2, 'abc')
.AsString;

Which will give you:



INSERT INTO Test (Column1, Column2) VALUES (42, 'abc')


Saturday, July 04, 2015

Using OmniThreadLibrary’s Message Queue with a TThread Worker

A reader recently asked about using OmniThreadLibrary’s communication channels with a TThread-based worker thread so I prepared a simple example, now part of the OTL repository (stored in the folder examples\TThread communication).
Two separate topics are covered in this example:
  • Sending data from any thread (main or background) to a TThread-based worker.
  • Sending data from a TThread-based worker to a form.

Friday, May 15, 2015

OmniThreadLibrary – GetIt!

OmniThreadLibrary is now available on GetIt so it can be installed in XE8 with a single click!

image
Go, Embarcadero! That’s really great!

Thursday, May 14, 2015

XE8 links

In case you’d like to know more about the RAD Studio/Delphi/C++ Builder XE8, following links will give you a good starting point.

Thursday, May 07, 2015

Presenting XE8 in Slovenia

Next Thursday (14th) I’ll be presenting XE8 in Ljubljana. We’ll be doing the standard “launch” combo – official (English) slides and demos + Slovenian presentation.

Register here!

Thursday, April 30, 2015

Runtime SQL Query Builder v3

There’s a whole new SQL Query Builder available on GitHub. I have basically rebuilt it from scratch as the previous “architecture” (it does not actually deserve to be called that) was just slapping strings together and that approach had reached its limits.

Query builder is now implemented as three units – GpSQLBuilder.AST implements an abstract syntax tree for SQL queries, GpSQLBuilder.Serialize knows how to serialize this tree to a string and GpSQLBuilder creates the tree and calls the serializer when necessary. Now it will be much simpler to a) add support for new SQL keywords and b) create different serializers, for example a ‘pretty print’ version. (If anybody wants to tackle this last task, please go ahead – I’ll be happy to merge a pretty print serializer into the master branch.)

In addition to that I have added support for different Joins: .InnerJoin, .RightJoin, and .FullJoin are now supported in addition to .LeftJoin.

A .&Case method was redesigned a bit. It now returns an interface which can be sent as a parameter to a .Select, .Column, and .OrderBy methods. You can use it like this:

  query := CreateGpSQLBuilder
.Select(
CreateGpSQLBuilder
.&Case
.When([COL_2, '< 0']).&Then('0')
.When([COL_2, '> 100']).&Then('2')
.&Else('1')
.&End)
.From(DB_TEST);

and

  query := CreateGpSQLBuilder;
query
.Select.All
.From(DB_TEST)
.OrderBy(
query.&Case
.When([COL_2, '< 0']).&Then(COL_3)
.&Else(COL_4)
.&End
);

New version also supports the .Distinct select flag.

I’ve created a unit test suite (actually I did that before the redesign so that I could refactor my code in piece) which now includes 51 tests, all passing.

Wednesday, April 29, 2015

Portable OmniThreadLibrary

If you care about running OmniThreadLibrary on mobile devices and on OS X, please join the OmniThreadLibrary-For-Mobile-DevelopmentProject page on Google+ where Sean has started to document his progress on doing exactly that – breaking the chains of Windows and bringing OmniThreadLibrary to all supported platforms!

Go, Sean!

Saturday, April 25, 2015

Value Never Used – Or Is It?

Sometimes, dcc32 is just plain stupid …

I have this code in the OmniThreadLibrary:

function TOmniThreadPool.Cancel(taskID: int64): boolean;
var
res: TOmniWaitableValue;
begin
{$IF CompilerVersion >= 22}
Result := false; // not really used
{$IFEND}
res := TOmniWaitableValue.Create;
try
otpWorkerTask.Invoke(@TOTPWorker.Cancel, [taskID, res]);
res.WaitFor(INFINITE);
Result := res.Value;
finally FreeAndNil(res); end;
end
;

The IFDEF part is there because otherwise compiler complains about result being potentially undefined.


[DCC Warning] OtlThreadPool.pas(1315): W1035 Return value of function 'TOmniThreadPool.Cancel' might be undefined


I’ve first observed this with the XE and it was fixed after the XE2 (can’t repeat this with XE8, but I didn’t check every compiler inbetween.)


Friday, April 17, 2015

New Home for OmniThreadLibrary

OmniThreadLibrary has been moved from Google Code to GitHub.

I still have to move existing issues as they were not moved automatically.

Thursday, April 16, 2015

New Home for My Units

My collection of open-sourced units has been moved from Google Code to GitHub.

Wednesday, April 08, 2015

XE8 is out …

… and OmniThreadLibrary works fine with it. (That’s it. Just wanted to let you know.)

Friday, April 03, 2015

Runtime SQL Query Builder

I don’t want to use long SQL strings in the code.

Really.

Firstly, it is a pain to write long multiline strings in Object Pascal. (Embarcadero, are you listening? Can we please get multiline strings in Delphi? Please?)

Secondly, I’m very OCD when it comes to compiler watching my every step. I absolutely hate runtime errors and I want every problem to be detected during the compilation. That includes typos in database field names and changes attributed to the entropy (i.e. changes in the database structure).

On a tangent, that’s why we are creating and managing tables and databases in the code. We have all fields defined as constants, all SQL statements created in runtime and everything stored under version control.Upgrading a database to a version required by the program is therefore a very simple operation. (Downgrading is still a problem. Downgrading is hard.)

Thirdly, concatenating query strings together when you are dynamically building a query string based on the conditions in the program is a mess.

That’s why long years ago I created a simple runtime query builder. It was dormant (in the “good enough for me” state) for a long time but recently I required more functionality from it and I extended it further. It is now in a state which may be useful for somebody else but me so I’m releasing it as an open source under a BSD license.

For impatient: Get GpSQLBuilder on GitHub.

Thursday, March 19, 2015

Unit Testing Recap & Downloads

The Unit Testing workshop was pretty much full.

2015-03-19 11.06.12

It was good to see that many interested Delphi programmers in one room. Thanks for coming, everybody!

The downloads for the workshop are now online.

Thursday, March 12, 2015

What’s New in Delphi XXXX

A great list of “What’s new” for Delphis from 3 to XE7 can be found on StackOverflow.

(just noticed and thought I’d better pass this on)

Wednesday, March 11, 2015

Unit Testing, Mocking, Inversion of Control

On March 19th (that’s next Thursday), I’ll be leading a workshop dedicated to unit testing Delphi programs. We’ll start with basics and and cover different tools (DUnit, DUnit2, DUnitX, TestInsight) and different programming methodologies.

Register here.

Sunday, March 01, 2015

OmniThreadLibrary 3.04

OmniThreadLibrary 3.04 is now released. Get it here or check out the release-3.04 tag (or just follow the trunk, which is the best way to experience the OmniThreadLibrary).

Some other links you may need:

Home page: http://www.omnithreadlibrary.com/
Google+ community: https://plus.google.com/communities/112307748950248514961
Downloads: https://drive.google.com/folderview?id=0BwqVlLNTK4OxVEgzZnZGM1FNMGc&usp=sharing#list
Issue tracker: http://code.google.com/p/omnithreadlibrary/issues/list
SVN checkout instructions: http://code.google.com/p/omnithreadlibrary/source/checkout
Author's blog: http://thedelphigeek.com
Author's home page: http://primoz.gabrijelcic.org
Documentation wiki: http://otl.17slon.com/book/
Documentation book: http://leanpub.com/omnithreadlibrary

Changelog

New features

  • Implemented simple and fast Parallel.&For which supports only integer ranges.
  • Implemented Parallel.Map.
  • Added overloaded Execute methods to IOmniParallelInitializedLoop and IOmniParallelInitializedLoop<T> so that IOmniTask parameter can be passed to the executor.
  • Implemented Run overloads that internally call Invoke to start thread worker.
  • Implemented TOmniValue.HasArrayItem.
  • Implemented TWaitFor which supports waiting any/all and is not limited to 63 objects.
  • IOmniTaskControl can wait on any number of comm handles and wait objects. That enables support for >60 tasks in the OtlThreadPool.
  • Implemented TOmniBlockingCollection.ToArray<T>.
  • NumTasks parameter (OtlParallel) can be negative. In that case, specified number of cores will be reserved for other purposes and all other will be used for processing.
  • Example: If NumTasks(-2) is used when process has access to 8 cores, 6 of them (8 - 2) will be used to run the task. 
  • Removed project groups.
  • Tested with 2007-XE7.

Bug fixes

  • Fixed race condition in IOmniPipeline termination code [tnx to Dean Hill].
  • Creating parameters with the array overload (IOmniTaskControl.SetParameters(['From', 0, 'To', 99])) was not working.
  • Fixed problems in demos 33_BlockingCollection and 47_TaskConfig.

New demos

  • 55_ForEachProgress: Demonstrates progress bar updating from a ForEach loop.
  • 56_RunInvoke: Simplified 'run & invoke' low-level API.
  • 57_For: Simple and fast parallel for.
  • 58_ForVsForEach: Speed comparison between Parallel.ForEach, Parallel.For, and TParallel.For (XE7+).
  • 59_TWaitFor: Demo for the new TWaitFor class.
  • 60_Map: Demonstrates the new Parallel.Map abstraction.
  • 61_CollectionToArray: Demonstrates the new TOmniBlockingCollection.ToArray<T> method

Wednesday, February 18, 2015

OmniThreadLibrary 3.04 Release Candidate

RC for the new OmniThreadLibrary release is available here.

This version should work with Delphis from 2007 to XE7. Win32 and Win64 are supported for Console and VCL applications.

Tuesday, February 03, 2015

Converting Collection to an Array

Blocking collections (IOmniBlockingCollection) are basic elements for data storage and transfer in many high-level OmniThreadLibrary abstractions. They can, however, be somewhat clumsy when you want to read data from them, as there is no indexed access, just the basic “give me next element” enumeration.

To help a bit, SVN now includes three new class functions in the TOmniBlockingCollection class – ToArray<T>, ToArrayIntf<T>, and ToArrayRec<T>.

class function ToArray<T>(coll: IOmniBlockingCollection):
TArray<T>;
class function ToArrayIntf<T: IInterface>(
  coll:
IOmniBlockingCollection): TArray<T>;

class function ToArrayRec<T: record>(
  coll:
IOmniBlockingCollection): TArray<T>;


Friday, January 30, 2015

Parallel Map

At my latest parallel programming presentation a participant suggested that I should extend the OmniThreadLibrary with a parallel mapping abstraction. Dear sir, here is a gift for you.

var
numbers: TArray<integer>;
odds : TArray<string>;
begin
//initialize the `numbers` array (not shown)
odds := Parallel.Map<integer,string>(numbers,
function (const source: integer; var dest: string): boolean
begin
Result := Odd(source);
if Result then
dest := IntTostr(source);
end);
//do something with the `odds` array (not shown)
end
;

Saturday, January 10, 2015

Implementing Record Assignment Operator [2]

Yesterday I hinted at having a working (and easy to use) solution which allows you to detect a record assignment (or copying, if you want) and to access both records (left and right part of the assignment operation). You can also modify record data when an assignment is detected. I also mentioned that my approach is very ugly, unstable, likely to cause problems in future Delphis and so on. You should read this article for the technical details, not to really use my code in an application. You have been warned!

Before I jump to hardcode Delphi stuff, I’d like to mention few different approaches that various smart people have already implemented. Most of them slipped below my radar in the past – and I’m guessing this may be the case for you too – so I’m listing them here in case you want to do more research on the topic.

Friday, January 09, 2015

Implementing Record Assignment Operator [1]

Following the yesterday’s hunch, I did some research and I came up with a way to detect when a record is copied (simple, supported, working everywhere) and even to access both records (source and target) during that operation (unsafe, unsupported and currently working only for Win32).

Now I can write such code:

Thursday, January 08, 2015

Implementing Destructor for a Record

Smart records in Object Pascal are very nice, but they have a stupid limitation – you cannot implement a destructor for a record.

image

A solution for that is quite simple and can be found all over the internet – add an interface to this record and implement the cleanup in this interface. To make it even simpler, you can use the IGpAutoExecute interface from the completely free GpStuff unit.