Question

I have a system I'm working on that has almost all of its logic in SQL Server stored procedures. As part of improving the development practices we want to move to a continuous delivery model using feature flags (aka toggles) to enable functionality in production.

How can I write the stored procs so that they check the flags efficiently and don't add load to the database by hammering a config table every time the procs are called?

Was it helpful?

Solution

I'm not convinced you need to prematurely optimize for a performance problem you don't know is going to exist. If your table has 100 rows and it's referenced often, it will almost certainly be in memory 100% of the time and access will be a non-issue.

One way that we have made code forward-compatible is to add a parameter to the procedure, with a default value, and the app can "upgrade" when the app is ready to do so. This can be done via a config file parameter, but presumably the app would have to be re-compiled to take advantage of the new functionality anyway.

As a quick example:

CREATE PROCEDURE dbo.doStuff
  @version DECIMAL(10,2) = 1.0
AS
BEGIN
  SET NOCOUNT ON;

  IF @version >= 1.1 
  BEGIN
    PRINT 'This only executes if the app tells us it is 1.1 or newer.';
  END

  IF @version >= 2.5
  BEGIN
    PRINT 'This only executes if the app tells us it is 2.5 or newer.';
  END
END
GO

When all of the apps are up to date, you can increase the base version on the parameter. Otherwise they can all be updated at their own rates, and the schema can progress at a different rate. If you can correlate each feature to a sequential point release, this shouldn't be too difficult to manage. But again I'll insist that a 100-row table is not going to drag your performance down as much as you seem to think it will...

OTHER TIPS

You can use CONTEXT_INFO to store 128 bytes of flags for the lifetime of your session or connection.

Create a function to retrieve the flags values:

create function dbo.GetConfigFlags() returns VarBinary(128)
  begin
  -- Retrieve the configuration flag values.
  --   This can be context sensitive, e.g. return different values based on user, server, ... .
  declare @Result as VarBinary(128)
  if Context_Info() is NULL
    set @Result = 12345 -- Get value from table or hard code here.
  else
    set @Result = Context_info()
  return @Result
  end

Start each stored procedure with code that gets the flags if they are not already loaded:

if Context_Info() is NULL
  begin
  declare @ConfigFlags as VarBinary(128) = dbo.GetConfigFlags()
  set Context_Info @ConfigFlags -- This is not allowed within a function.
  end
select Context_Info() -- Demo.

The ugly part is managing meanings for the bits.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top