1 2 3 4 5 6 7 8 9 10 11
On project maintenance

Consider the following scenarios:

  • You maintain a legacy project or your once-greenfield project has now turned a year (or two) old
  • You’ve been busy programming and have been pummelled by project admin

Under the stresses that come with the combination of these two scenarios, software developers often overlook one critical aspect to a successful, future-proof project: external package-maintenance.

I recently sat down and wrote an email explaining how I go about package-maintenance and thought it would be useful to write up those notes and share them with others.

The tech world moves quickly; new code styles, frameworks and best practices evolve in the blink of an eye. Before you know it, the packages you'd installed the previous year are no longer documented and there aren’t any blogposts describing how to upgrade them to their latest versions. Nightmare.

My general rule of thumb to avoid this ill-fated destiny is to set aside some time each sprint to upgrade packages. The process isn’t really involved, but it can be time-consuming if you upgrade a handful of packages at once and find that one of them breaks your code. You then have to go through each, one by one, downgrade and figure out if it’s the culprit.

My upgrade procedure (in this case using the yarn package manager) is:

  • Check which packages are due for upgrade - yarn outdated
  • Look through the READMEs for each of the outdated packages and check if any of the changes are likely to impact your codebase
  • Upgrade those packages that don’t appear to significantly have changed - yarn add clean-webpack-plugin@latest or yarn add clean-webpack-plugin@VERSION_NUMBER to install a specific version
  • Run the project’s test suite and check if the application still works. Fix any issues as required
  • Repeat for packages that have significantly changed

Tom Szpytman is a Software Developer at Encodo and works primarily on the React/Typescript stack

v4.1.5: Calculated Properties and Delegate Expressions

The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes and is available to those with access to the Encodo issue tracker.

Highlights

Breaking changes

Tuple support for delegates

tl;dr: Applications might have to include the System.Tuple NuGet package in some assemblies.

This release adds an overload for creating delegate expressions that returns a Tuple (object, bool). This improvement allows applications to more easily specify a lambda that returns a value and a flag indicating whether the value is valid.

There are several overloads available for creating a DelegateExpression. The simplest of these assumes that a value can be calculated and is appropriate for constant values or values whose calculation does not depend on the IExpressionContext passed to the expression.

However, many (if not most) delegates should indicate whether a value can be calculated by returning true or false and setting an out object value parameter instead. This is still the standard API, but 4.1.5 introduces an overload that supports tuples, which makes it easier to call.

In 4.1.4, an application had the following two choices for using the "tryGetValue" variant of the API.

Elements.Classes.A.AddCalculatedProperty("FullText", f => f.CreateDelegate(GetFullText));

private object GetFullText(IExpressionContext context, out object value)
{
  var obj = context.GetInstance<IMetaObject>();
  if (obj != null)
  {
    value = obj.ToString();
		 
    return true;
  }

  value = null;
	
  return false;
}

If the application wanted to inline the lambda, the types have to be explicitly specified:

Elements.Classes.A.AddCalculatedProperty("FullText", f => f.CreateDelegate((IExpressionContext context, out object value) => {
  var obj = context.GetInstance<IMetaObject>();
  if (obj != null)
  {
    value = obj.ToString();
		 
    return true;
  }

  value = null;
	
  return false;
}));

The overload that expects a tuple makes this a bit simpler:

Elements.Classes.A.AddCalculatedProperty("FullText", f => f.CreateDelegate(context => {
  var obj = context.GetInstance<IMetaObject>();
	 
  return obj != null ? (obj.ToString(), true) : (null, false);
}));

Empty Expression Contexts

Previously, a DelegateExpression would always return false for a call to TryGetValue() made with an empty context. This has been changed so that the DelegateExpression no longer has any logic of its own. This means, though, that an application must be a little more careful to properly return false when it is missing the information that it needs to calculate the value of an expression.

All but the lowest-level overloads and helper methods are unaffected by this change. An application that uses factory.CreateDelegate<T>() will not be affected. Only calls to new DelegateExpression() need to be examined on upgrade. It is strongly urged to convert direct calls to the construct to use the IMetaExpressionFactory instead.

Imagine if an application used a delegate for a calculated expression as shown below.

Elements.Classes.Person.AddCalculatedProperty("ActiveUserCount", MetaType.Boolean, new DelegateExpression(GetActiveUserCount));

// ...

private object GetActiveUserCount(IExpression context)
{
  return context.GetInstance<Person>().Company.ActiveUsers;
}

When Quino processes the model during startup, expression are evaluated in order to determine whether they can be executed without a context (caching, optimization, etc.). This application was safe in 4.1.4 because Quino automatically ignored an empty context and never called this code.

However, as of 4.1.5, an application that calls this low-level version will have to handle the case of an or insufficient context on its own.

It is highly recommended to move to using the expression factory and typed arguments instead, as shown below:

Elements.Classes.Person.AddCalculatedProperty<Person>("ActiveUserCount", MetaType.Boolean, f => f.CreateDelegate(GetActiveUserCount));

// ...

private object GetActiveUserCount(Person person)
{
  return person.Company.ActiveUsers;
}

If you just want to add your own handling for empty contexts, you can do the following (note that you have to change the signature of GetActiveUserCount):

Elements.Classes.Person.AddCalculatedProperty("ActiveUserCount", MetaType.Boolean, new DelegateExpression(GetActiveUserCount));

// ...

private bool GetActiveUserCount(IExpression context, out object value)
{
  var person = context.GetInstanceOrDefault<Person>();
  if (person == null)
  {
    value = null;
    return false;
  }

  value = person.Company.ActiveUsers;

  return true;
}
v4.1.4: Search-detail fixes and calculated properties

The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes and is available to those with access to the Encodo issue tracker.

Highlights

Breaking changes

  • None
v4.1: Layouts, captions, multiple requests-per-connection

The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes and is available to those with access to the Encodo issue tracker.

Highlights

Breaking changes

  • Usages of {{RunWinform}} should be updated to {{RunMetaWinform}}. The method {{RunWinform}} is now defined with a function parameter that expects an {{IApplication}} parameter instead of an {{IDataSession}} parameter. The change was made to allow applications more flexibility in configuring startup for applications with multiple main forms (QNO-4922) while still re-using as much shared code in Quino as possible. {{RunMetaWinform}} extends the {{RunWinform}} support to create and configure an {{IDataSession}} per form.
v4.1.3: Fixes for search layouts, languages, reconnects, descendant relations

The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes and is available to those with access to the Encodo issue tracker.

Highlights

  • Fixed reconnect for ADO database connections (QNO-5776)
  • Fixed occasional startup crash when generating data (QNO-5768)
  • Improved search-layout / search-class generation (QNO-5767)
  • Restored support / example for toggling data languages in the UI (QNO-5764)
  • Fixed save for relations with descendant endpoints (QNO-5753)

Breaking changes

  • None
Quino Release Notes

The following is a complete list of all Quino release notes, from newest to oldest. See the roadmap for future releases.

Windows 10 Fall Creators Update

At Encodo, we're much more cautious about installing massive Windows updates. Since a couple of us (including me) have started experiencing memory leaks in the previous version, we installed it on select machines.

Memory Leak fixed?

The memory leak we were experiencing was only on a couple of machines. It manifested as Task Manager reporting a very high RAM-usage percentage and, occasionally, Windows popping up a message box asking to close applications. Also, Win + S no longer responded on the first try (i.e. the Windows shell became only partially responsive).

Investigating with the RAMMap tool from Microsoft revealed a large amount (8GB) of "Process Private" RAM that couldn't all be accounted for in Task Manager or the Resource Monitor.

Initial results are better and seem to indicate normal behavior: if an application that uses a lot of RAM (e.g. Visual Studio) is closed, the reported RAM usage drops correspondingly.

NB; this is not at all a scientific conclusion. We applied the update and memory management on a previously misbehaving machine is better. That's all.

Task Manager

The Task Manager has two immediately obvious improvements:

  • All of an application's related processes are now collected under that application's node in the Task Manager. This is most obvious for web browsers, for which a much more realistic -- and, possibly, scary -- RAM-usage figure is shown. Other applications, like Visual Studio and even iTunes (as shown in the screenshot below, benefit). This gives the user a much clearer picture of which applications are actually using resources, even if they have been split into multiple processes.
  • % GPU usage is now a default column. You can now see that your web browsers are making good use of all hardware, where appropriate.

One drawback, though, is that you can no longer see which solution is open in which instance of Visual Studio.

Aero Shake

Microsoft, as usual, has re-enabled settings that you may have turned off. They did this with the mind-boggling feature called "Aero Shake": when you grab a Window title and shake it with the mouse, all other Windows are minimized. At first, just the feature was bizarre; now, it's Microsoft's fixation with re-enabling this feature that is truly worrying.

We've disabled it in the group policies on our domain controller so our users never have to suffer again.

Conclusion

We have not found any drawbacks to this update with our software and development tools and will roll it out to the rest of our users immediately.

v5.0: Bootstrap IOC, authorization driver, improve dependencies

The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes below and is available to those with access to the Encodo issue tracker.

Notes

Quino 4 was released on 11. August, 2017. Quino 4.1.7 brings that venerable line to a close. Products are encouraged to upgrade to the this version as the next stable build with the improvements outlined below.

Highlights

Breaking changes

  • ApplicationBasedTestsBase.CreateApplication() has a new parameter (bool isFixtureApplication). Applications that override this method will have to adjust their definition.
  • PathTools methods are deprecated. In some cases, these methods have been marked as obsolete (true), which causes a compile error. The obsolete message indicates which method to use instead.
  • ICommandSetManager.Apply() no longer has a IValueTools parameter
  • RegisterStandardConnectionServices has been renamed to RegisterApplicationConnectionServices
  • IValueTools.EnumParser is no longer settable; register your object/implementation in the Bootstrap instead
  • Methods from DataMetaExpressionFactoryExtensions has been removed. Instead of creating expressions directly with the expression factory, you should use the query or query table.
  • IQueryCondition no longer has a type parameter (it used to be IQueryCondition<TSelf>)
v4.1.2: Expressions and code-generation

The summary below describes major new features, items of note and breaking changes. The full list of issues is in the release notes and is available to those with access to the Encodo issue tracker.

Highlights

  • Fix code-generation for modules with no classes (QNO-5722)
  • Restore ExpressionConstants.Now (QNO-5720)
  • Improve backwards-compatibility for wrappers (QNO-5744)

Breaking changes

  • None