Saturday, September 8, 2007

K2.net General Best Practices

This is the first of a series of best practices I considered when starting a new workflow. Note that manye of these Best Practices are K2.net 2003 specific. They will be re-evaluated with the new BlackPearl release.

1) Start with Use Cases & Process Flow Diagram
Prior to doing your workflow, start with the creation of use cases as they can be used to design a workflow. Use tools like Visio or K2 Studio itself to create process flows to show to the business users. With BlackPearl, the Visio diagrams can be imported into K2.

2) Plan on Reporting
With K2.net 2003 the Workspace website provides several out of the box reports on the health of all processes. They can be used to support development and administrative activities. They sometimes do not do well with business users as low level implementation details are exposed which can become confusing. Consider storing key business data externally in reporting database using your reporting engine of choice. The K2 database is optimized for managing a state machine not for doing business reporting. BlackPearl provides a wizard to design reports I would still recommend doing externally reporting.

3) Maximize Use of Code Accelerators (Wizards)
Use the K2 Event Wizards to their fullest extent. If you do not know the code, but need to write some custom code, use an Event wizard to generate the code and then re-use it. It is not a short coming of K2.ne that a developer still needs to go into the generated code; it is advantage that much of this code is already built and is completely extendable. For instance, there are events for email, SQL, Data Manipulation, InfoPath, SharePoint, Web Services, BizTalk, Exchange, etc. Good .net developers will want to take the code generated and generalize it in a code library. That is fine approach but should be balanced with maximizing K2.net to create things quickly.

4) Code Modules
Code modules provide a quick way to centralize re-usable code that can be used in all processes defined in a solution. They are best used when created utility methods and functions. Singleton classes tend to work well with code modules. If full object orientated libraries are needed it is better to create an external class library in Visual Studio.

5) Using External Libraries Versioning
External code library should be considered if there is a need for complex classes. If the classes can be used in other context outside of K2.net, it is recommended the class definitions be absolutely externalized. Note that referenced K2.net libraries will be exported with the K2.net process definition to the K2.net server (the dll is serialized into the database).

There are considerations that must be thought of before placing the external DLL that K2.net will use in the GAC. Even though the DLL is versioned in the GAC there is no version mapping to the K2.net process definition that has been exported to the K2.net server. If the code has volatile business rules being computed with long running processes, creating an external service to access that code library is the suggested best practice.

Typically it is just best to create an external library in Visual Studio and import that directly in the K2.net process but there are still some considerations. Note that configuration files will have to be manually pushed to the production server and there can only be one config file for the K2 Server requiring all of the external DLLs so share the same config.

Finally errors in external libraries can be particularly hard to debug without logging. They are even harder or impossible to repair using the K2.net Service Manager without going through a lot of effort.

6) Use String Table for Configuration Values
Use the K2.net string table to place all configurations for your processes. Complex configurations (repeating data) cannot be managed inside of string table. A configuration file can be created in the K2.net bin directory it is recommend that an external database be used to retrieve configuration or process metadata if it is particularly complex.

7) Provide Users with Multiple Ways to Access Assigned Tasks
Provide users with multiple ways to complete the tasks that they have been assigned. Relying completely on email as a way to distribute links to an InfoPath or ASP.net form is not good as the email can be lost or deleted.

8) Using K2.net ROM in Server Event
The K2.net ROM should never be used in a server event when it is accessing the current process instance. Attempting to use the K2.net ROM to operate on the current process instance from within the execution of the current process instance can result in inconsistent behavior and/or crashing of the K2.net Server service. This because is the K2.net server locks the processes that is currently executing and cannot connect back to itself with the external K2.net ROM as described. [1] It is alright to use the K2.net ROM to create new process instances (similar to using an IPC sever event) or to finish the event of a different process. The golden rule is to not use the K2.net ROM on the current process instance itself, only on other process instances.

9) Design with Testing in Mind
Having a K2.net development and QA server should be highly considered. It is possible to create unit tests using Visual Studio 2005 test projects the can unit test an entire workflow and all of its permutations. This is done by using the K2.net ROM to create process instances and mimic user events that push the workflow through. [2]

10) Use Source Control and Define File Hierarchy
It is highly recommended the version control be used to manage K2.net solutions. With BlackPearl integrated into Visual Studio working with source control becomes much easier!

11) Activity Logic Considerations
11.1) Line Rule Must be True to Continue
A common mistake when designing K2.net process is to have activities that will stop a K2.net process instance. If the activity has no lines extending from it or none that will result with a true value the K2.net process instance will finish and cannot be restarted again. It is suggested to pseudo code your line rules on paper to avoid this issue.

11.2) Line Rule Custom Code
Custom code in the Line Rules should only have code that is used determined if something is true or false; do not embed something like a write operation. All line rules are executed NOT matter what and other line rules will be affected. In general, whenever you put custom code into an event handler for line rules, events, preceding, succeeding, etc. make sure the code placed in there is for that operation only.

11.3) Graceful Cancel out of a Workflow
Most workflows will require paths to gracefully cancel or stop a workflow. Make sure this is incorporated into the design of the process definition from the beginning.

11.4) Design for Delegation
Make sure that there is functionality to delegate or escalate so process instances can be re-assigned by the users themselves (even though this will be done through the K2 Service Manager). When delegating, events that are places before the client event will be re-executed. Ensure that there are no problems with iterating over the same code more than once; otherwise move the event.

12) Logging
Ensure Logging is turned on in the K2.net server and logging has been implemented within code.

13) Unique Name in Folio
Processes allow for a Folio Name which is a readable name for a K2.net process instance; use them.

14) Do not Let K2 Spam
Escalations with email can quickly become a spam machine. Ensure that the setting for the duration for escalations is configurable through the string table or a database. As well, create a configuration to turn off escalations in the string table and use it in the event handler for the escalation.

No comments: