Web Api Caching and resolving issues

8 posts, 1 answers
  1. Colin
    Colin  avatar
    18 posts
    Member since:
    Aug 2014

    Posted 16 Apr 2015 Link to this post

    Hi

     

    I have a Web Api project with Telerik reporting, and a client Angular site that hosts the reportviewer.

    The report files are compiled into the dll, ie. are not trdx files

     

    I have had the following issues.

    The initial call works and the report is displayed. However, subsequent calls just redisplay the initial report. I have verified this by changing the report and recompiling, as well as making changes in the database, yet the report does not change.

    My ReportsController is 

     

    protected override IReportResolver CreateReportResolver()
    {
        return new ReportTypeResolver();
    }
     
    protected override ICache CreateCache()
    {
       return Telerik.Reporting.Services.Engine.CacheFactory.CreateFileCache();
    }

     

    I tried to resolve this by overriding CreateStorage

    protected override IStorage CreateStorage()
    {
        return new MsSqlServerStorage(@"Server=.\BF;database=Reporting;Integrated Security=true");
    }

    But when I do this I get a timeout exception when the report is being resolved 

    Error creating report instance (Report = NPS.Reports.Simple, NPS.Reports):
    An error has occurred.
    Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.

    I have  the Fiddler trace as well as the SQL Server profiler trace, but cannot attach them so I have just attached screenshots.

    The full exception is

    stackTrace=   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
       at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
       at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
       at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
       at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
       at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
       at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
       at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
       at Telerik.Reporting.Cache.MsSqlServerStorage.AcquireLock(String key)
       at Telerik.Reporting.Services.Engine.KeyItemPersistableCollection`2.ResolveItem(K referredInstanceKey, Boolean& newItem)
       at Telerik.Reporting.Services.Engine.ReportEngine.CreateReportInstance(String clientID, String report, Dictionary`2 parameterValues)
       at Telerik.Reporting.Services.WebApi.ReportsControllerBase.CreateInstance(String clientID, ClientReportSource reportSource)
       at lambda_method(Closure , Object , Object[] )
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()

    Note that for this trace I used a very simple report that has no parameters and no datasource, just a single textbox.

    Thanks

     

    Colin Mierowsky

  2. Answer
    Doug
    Doug avatar
    1 posts
    Member since:
    Jan 2015

    Posted 20 Apr 2015 in reply to Colin Link to this post

    I had a similar issue a few weeks ago with version 9.0.15.225, which I see you're running as well.  I contacted support and they had me download and upgrade to 9.0.15.324 because there was a bug in DB caching that caused table locks of some sort.  Since I upgraded, DB caching has been running smoothly for me.  Hope this helps...
  3. DevCraft banner
  4. Colin
    Colin  avatar
    18 posts
    Member since:
    Aug 2014

    Posted 20 Apr 2015 in reply to Doug Link to this post

    Doug

     Thanks for that, the upgrade did solve the timeout / locking problem.

    However, my initial problem of the reports not refreshing is still occurring, and this is irrespective of whether I override CreateCache with a File case or a database cache, or override CreateStorage with a MsSqlServerStorage.

    I have now done some more investigation, and will start a new thread more focused on the actual problem.

    Regards

     

    Colin

  5. Stef
    Admin
    Stef avatar
    3041 posts

    Posted 21 Apr 2015 Link to this post

    Hello Colin,

    This is the default cache mechanism behavior, where reports rendered on the server with a given set of parameters are reused if there is a request for the same report with the same set of parameters.

    Calling the viewer's refreshReport method (use the method or the toolbar's refresh button), once the viewer is ready and loaded or the underlying data is updated, must cause the report to be processed, rendered and cached again.

    Another recommended approach is to have a DateTime report parameter, which value is updated on each preview in the viewer (always pass DateTime.Now as value). The new parameter's value will force the reporting engine to process again the report.

    Our developers consider providing options for setting the expiration time of the cache in a consecutive release
    , which will allow you remove rendered pages on a specific time interval.

    Regards,
    Stef
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  6. Colin
    Colin  avatar
    18 posts
    Member since:
    Aug 2014

    Posted 22 Apr 2015 in reply to Stef Link to this post

    Hi  

    Thanks for that.

     

    I believe you definitely need to add the ability to set the timeout period, as there are many cases where the data is volatile and cached reports will always be stale. What is the timeout set to, i.e. how long are reports currently cached?

     

    I tried the refreshReport method, but this did not help so I have add a time parameter which has solved my problem.

     

    Regards

     

    Colin

     

  7. Stef
    Admin
    Stef avatar
    3041 posts

    Posted 27 Apr 2015 Link to this post

    Hi Colin,

    The default time is 30 minutes, where the time extends while the cached report instance is in use. If the cache instance is not used for 30 minutes, a consecutive request to the Reporting REST service clears the cached report.


    The feature with setting the cache timeout can be found in the latest available internal build v9.0.15.422 (Telerik Reporting Q1 2015 SP1).

    Please test the following:
    1. Download and install the latest available Telerik Reporting Q1 2015 Sp1 internal build v9.0.15.422 (download link);
    2. Run the Upgrade Wizard for all projects having references to Telerik Reporting;
    3. Edit the ReportsControllerBase implementation based on the local examples:
      namespace CSharp.MvcDemo.Controllers
      {
          using System.IO;
          using System.Web;
          using Telerik.Reporting.Cache.File;
          using Telerik.Reporting.Services;
          using Telerik.Reporting.Services.Engine;
          using Telerik.Reporting.Services.WebApi;
        
          public class ReportsController : ReportsControllerBase
          {
              static ReportServiceConfiguration preservedConfiguration;
        
              static IReportServiceConfiguration PreservedConfiguration
              {
                  get
                  {
                      if (null == preservedConfiguration)
                      {
                          preservedConfiguration = new ReportServiceConfiguration
                          {
                              HostAppId = "MvcDemoApp",
                              Storage = new FileStorage(),
                              ReportResolver = CreateResolver(),
                              // CachedReportTimeout = 0,
                              // ClientSessionTimeout = 15,
                          };
                      }
                      return preservedConfiguration;
                  }
              }
        
              public ReportsController()
              {
                  this.ReportServiceConfiguration = PreservedConfiguration;
              }
        
              static IReportResolver CreateResolver()
              {
                  var appPath = HttpContext.Current.Server.MapPath("~/");
                  var reportsPath = Path.Combine(appPath, @"..\..\..\Report Designer\Examples");
        
                  return new ReportFileResolver(reportsPath)
                      .AddFallbackResolver(new ReportTypeResolver());
              }
        
              //protected override ICache CreateCache()
              //{
              //    return Telerik.Reporting.Services.Engine.CacheFactory.CreateFileCache();
              //}
          }
      }
      In the above code uncomment the CachedReportTimeout to avoid the reports caching.

    I hope this helps you.

    Regards,
    Stef
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  8. Grant
    Grant avatar
    8 posts
    Member since:
    Aug 2011

    Posted 11 Jul Link to this post

    Hi,

    I am using version 10.1.16.615 and there is no property ReportServiceConfiguration.CachedReportTimeout. Has it been renamed to ReportSharingTimeout ?

     

     

  9. Stef
    Admin
    Stef avatar
    3041 posts

    Posted 12 Jul Link to this post

    Hi Grant,

    The cache settings of the Reporting REST service are ClientSessionTimeout and ReportSharingTimeout - valid for R2 2016 release. More details about each and how the cache mechanism works can be found in Cache Management.


    I hope this helps.

    Regards,
    Stef
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
DevCraft banner