Base solution for your next web application

Activities of "TimMackey"

Product Version 8.0.0 Product Type: Angular Framework: .NET Core 3.0 ABP Framework: 5.0

I'm currently using the BackgroundJob class successfully. Some jobs execute in few seconds. Other jobs execute in minutes or hours. Each job is independent, with no dependency on previously executed jobs. Jobs are initiated by user actions. Long running jobs cause fast running jobs to wait until the long running job has finished because BackgroundJob executes queued jobs sequentially. This causes one user's job to wait until all other jobs have run to completion. How can I implement "fire and forget" jobs (or Tasks) that execute in parallel? I want a user's job to begin execution immediately.

Below are code snippets of the current implementation:

    [AbpAuthorize(AppPermissions.Pages_Exams)]
    public class ExamsAppService : ngTTMAppServiceBase, IExamsAppService
    {
        .
        .
        .
        [AbpAuthorize(AppPermissions.Pages_Exams_Create)]
        private async Task<ServiceStatusDto> CreateExamJob(string examGuid)
        {
            ServiceStatusDto status = new ServiceStatusDto(L("Exams"), L("Success"));
            long UserId = (long)AbpSession.UserId;

            string workingDirectory = _webHostEnvironment.ContentRootPath;

            try
            {
                CreatJobArgs args =
                    new CreatJobArgs
                    {
                        tenantId = AbpSession.TenantId,
                        userId = UserId,
                        jobGuid = examGuid,
                        folder = StorageLibrary.Storage.FILES_FOLDER,
                        operation = JobOps.JOB_OP_CREATE,
                        workingDirectory = workingDirectory
                    };

                using (_abpSession.Use(AbpSession.TenantId, UserId))
                {
                    status.BackgroundJobId = await
                        _backgroundJobManager.EnqueueAsync<CreateExamJob, CreatJobArgs>(args);
                }
                status.Guid = examGuid;
                return status;
            }
            catch (Exception ex)
            {
                ExceptionUtility.LogException(UserId, ex);
                status.Success = false;
                status.FailureReason = ex.Message;
                return status;
            }
        }
    }

=============================================

    public class CreateExamJob : BackgroundJob<CreatJobArgs>, ITransientDependency, IApplicationService
    {
        private readonly ITempFileCacheManager              _tempFileCacheManager;
        private readonly IWebHostEnvironment                _hostingEnvironment;
        private readonly ISettingManager                    _settingManager;
        private readonly ILocalizationManager               _localizationManager;
        private readonly IAbpSession                        _abpSession;
        private readonly IBinaryObjectManager               _binaryObjectManager;
        private DateTime jobStartTime;

        public CreateExamJob(
            ITempFileCacheManager                   tempFileCacheManager,
            ISettingManager                         settingManager,
            IWebHostEnvironment                     hostingEnvironment,
            ILocalizationManager                    localizationManager,
            IBinaryObjectManager                    binaryObjectManager,
            IAbpSession                             abpSession
        )
        {
            _settingManager = settingManager;
            _hostingEnvironment = hostingEnvironment;
            _tempFileCacheManager = tempFileCacheManager;
            _localizationManager = localizationManager;
            _binaryObjectManager = binaryObjectManager;
            _abpSession = abpSession;
        }
        
        [UnitOfWork]
        public override void Execute(CreatJobArgs args)
        {
            jobStartTime = DateTime.Now;

            using (CurrentUnitOfWork.SetTenantId(args.tenantId))
            {
                using (_abpSession.Use(args.tenantId, args.userId))
                {
                    UserIdentifier _userId = new UserIdentifier(args.tenantId, (long)args.userId);
                    string userLanguage = _settingManager.GetSettingValueForUser(LocalizationSettingNames.DefaultLanguage, _userId);
                    CultureInfo culture = CultureHelper.GetCultureInfoByChecking(userLanguage);
                    Thread.CurrentThread.CurrentUICulture = culture;
                    LocalizationSourceName = ngTTMConsts.LocalizationSourceName;

                    Execute_MyCode(args);       // How to "fire and forget" this?  Or an instance of the CreateExamJob class?
                }
            }
        }
    }

==========================================

    [Serializable]
    public class CreatJobArgs
    {
        public string fileToken { get; set; }
        public string folder { get; set; }
        public string jobGuid { get; set; }
        public string operation { get; set; }
        public int? tenantId { get; set; }
        public long? userId { get; set; }
        public string workingDirectory { get; set; }
    }
Answer
 「wdm」: Compiled successfully.
 
C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\webpack-dev-server\lib\servers\SockJSServer.js:67
      f(connection, connection.headers);
                               ^

TypeError: Cannot read property 'headers' of null
    at Server.<anonymous> (C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\webpack-dev-server\lib\servers\SockJSServer.js:67:32)
    at Server.emit (events.js:314:20)
    at App.emit (C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\sockjs\lib\sockjs.js:196:29)
    at C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\sockjs\lib\transport.js:111:25
    at processTicksAndRejections (internal/process/task_queues.js:75:11)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `ng serve --host 0.0.0.0 --port 4200`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Tim\AppData\Roaming\npm-cache\_logs\2020-09-25T23_13_53_115Z-debug.log

C:\Users\Tim\Documents\__ngTTMv800\angular>node
Welcome to Node.js v14.12.0.
Type ".help" for more information.
>

Have not tried on another machine. The easiest way to try on another machine would be to clone the SDD and plug disc into another laptop of identical HW. I doubt the outcome would be different, given the OS and all drivers, apps, packages are identical. The hard way would be to install all dev tools, apps and packages from a HDD set to original factory settings, which might have a different outcome. This would take a lot of time, and if the error goes away, the root cause would still remain unknown. Open to other diagnostic suggestions.

Answer

Upgraded to Node.js v12.18.4 (latest). Same error as above sequence:

C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\webpack-dev-server\lib\servers\SockJSServer.js:67
      f(connection, connection.headers);
                               ^

TypeError: Cannot read property 'headers' of null
    at Server.<anonymous> (C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\webpack-dev-server\lib\servers\SockJSServer.js:67:32)
    at Server.emit (events.js:315:20)
    at App.emit (C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\sockjs\lib\sockjs.js:196:29)
    at C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\sockjs\lib\transport.js:111:25
    at processTicksAndRejections (internal/process/task_queues.js:79:11)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `ng serve --host 0.0.0.0 --port 4200`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Tim\AppData\Roaming\npm-cache\_logs\2020-09-18T16_45_48_474Z-debug.log

C:\Users\Tim\Documents\__ngTTMv800\angular>node
Welcome to Node.js v12.18.4.
Type ".help" for more information.
>
Answer

This error consistently happens in the following scenario:

  1. In Visual Studio Code start debug session with Chrome browser.
  2. login as user [email protected]
  3. use website
  4. logout
  5. open Chrome browser.
  6. navigate to localhost:4200.
  7. login as user [email protected]
  8. node server crashes as soon as home page is displayed.
C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\webpack-dev-server\lib\servers\SockJSServer.js:67
      f(connection, connection.headers);
                               ^

TypeError: Cannot read property 'headers' of null
    at Server.<anonymous> (C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\webpack-dev-server\lib\servers\SockJSServer.js:67:32)
    at Server.emit (events.js:223:5)
    at App.emit (C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\sockjs\lib\sockjs.js:196:29)
    at C:\Users\Tim\Documents\__ngTTMv800\angular\node_modules\sockjs\lib\transport.js:111:25
    at processTicksAndRejections (internal/process/task_queues.js:76:11)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `ng serve --host 0.0.0.0 --port 4200`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Tim\AppData\Roaming\npm-cache\_logs\2020-09-17T18_23_20_738Z-debug.log

Current remedy: npm start

Your suggestion is the solution. Thank you.

private async Task<byte[]> GetBinaryObject(Guid guid)
{
	using (CurrentUnitOfWork.SetTenantId(1))
	{
		var file = await _binaryObjectManager.GetOrNullAsync(guid);
		if (file == null)
		{
			return null;
		}
		return file.Bytes;
	}
}

I posted the wrong code. Here is the correct code:

public override void Execute(CreateExamJobArgs args)
{
        var guid = new Guid("02729c9d-dae0-683b-1d8f-39f5844c75e9");
        var file = GetBinaryObject(guid);
}

private async Task<byte[]> GetBinaryObject(Guid guid)
{
    var file = await _binaryObjectManager.GetOrNullAsync(guid);
    if (file == null)
    {
        return null;
    }
    return file.Bytes;
}

Data in AppBinaryObjects: 02729c9d-dae0-683b-1d8f-39f5844c75e9 1 0x89504E470D0A1A0A0000000D494844520000008C000000A00806000000DEAE8473000000017352474200AECE1CE90000000467414D410000B18F0BFC61050000FDDA49444154785E4CFD65771C5BA22D0AFADD738A379B6531332B95CCCC99CA14A698999965C924C96C4B6690999937D7DEB58B0EBC7BEE7D6FF4A7EE0F3D46

When _binaryObjectManager.GetOrNullAsync(guid) is invoked in an AppService, a BinaryObject is returned, as expected:

_binaryObjectManager = {ngTTM.Storage.DbBinaryObjectManager}
_binaryObjectRepository = {Castle.Proxies.IRepository`2Proxy_17}
file = {[BinaryObject 02729c9d-dae0-683b-1d8f-39f5844c75e9]}

When invoked in a Background Job, a null object is returned, unexpected:

_binaryObjectManager = {ngTTM.Storage.DbBinaryObjectManager}
_binaryObjectRepository = {Castle.Proxies.IRepository`2Proxy_17}
file = null

I created a Background Job per the following instructions: Background Jobs

However, the _binaryObjectRepository does not appear to be connected to the db. var _all = _binaryObjectRepository.GetAllList(); does not cause Exceptions, but also does not return any values. How can I get this to work?

Also, maybe for another issue, _localizationManager only returns English language string - ignores all other language settings - returns English strings. These issues only appear in a Background Job. They work as expected in AppServices. Another clue: _settingManager works correctly as expected.

using Abp.Application.Services;
using Abp.BackgroundJobs;
using Abp.Configuration;
using Abp.Domain.Uow;
using Abp.Localization;
using Abp.Runtime.Session;
using Abp.Dependency;
using Abp.EntityFrameworkCore;
using ExceptionsLibrary;
using JobsLibrary;
using Microsoft.AspNetCore.Hosting;
using ngTTM.Storage;
using System;
using System.IO;
using Abp.Domain.Repositories;

#if EXAM_DB_CONTEXT_LIB
using DbContext = ExamDbContextLibrary.ExamDbContext;
#else
using ngTTM.TtmDataModel;
using DbContext = ngTTM.EntityFrameworkCore.ngTTMDbContext;
#endif

namespace JobManager
{
    //-----------------------------------------------------------------------------------------
    [Serializable]
    public class CreateExamJobArgs
    {
        public long userId { get; set; }
        public string guid { get; set; }
        public string operation { get; set; }
        public string folder { get; set; }
        public string workingDirectory { get; set; }
        public string fileToken { get; set; }
    }

    //-----------------------------------------------------------------------------------------
    public class CreateExamJob : BackgroundJob<CreateExamJobArgs>, ITransientDependency, IApplicationService
    {
        //=========================================================================================
        #region Private Fields
        //-----------------------------------------------------------------------------------------
        private readonly ITempFileCacheManager _tempFileCacheManager;
        private readonly IDbContextProvider<DbContext> _dbContextProvider;
        private readonly IWebHostEnvironment _hostingEnvironment;
        private readonly ISettingManager _settingManager;
        private readonly ILocalizationManager _localizationManager;
        private readonly IAbpSession _abpSession;
        private readonly IRepository<BinaryObject, Guid> _binaryObjectRepository;
        private readonly IBinaryObjectManager _binaryObjectManager;

        //-----------------------------------------------------------------------------------------
        #endregion Private Fields
        //=========================================================================================
        //-----------------------------------------------------------------------------------------
        public CreateExamJob(
            ITempFileCacheManager tempFileCacheManager,
            IDbContextProvider<DbContext> dbContextProvider,
            ISettingManager settingManager,
            IWebHostEnvironment hostingEnvironment,
            ILocalizationManager localizationManager,
            IRepository<BinaryObject, Guid> binaryObjectRepository,
            IBinaryObjectManager binaryObjectManager,
            IAbpSession abpSession
        )
        {
            //Debug.WriteLine("CreateExamJob.CreateExamJob()");
            _dbContextProvider = dbContextProvider;
            _settingManager = settingManager;
            _hostingEnvironment = hostingEnvironment;
            _tempFileCacheManager = tempFileCacheManager;
            _localizationManager = localizationManager;
            _binaryObjectRepository = binaryObjectRepository;
            _binaryObjectManager = binaryObjectManager;
            _abpSession = abpSession;
        }
        //----------------------------------------------------------------------------------------
        [UnitOfWork]
        public override void Execute(CreateExamJobArgs args)
        {
            try
            {
                var _all = _binaryObjectRepository.GetAllList();
                var alllist = _binaryObjectRepository.GetAllList(bo => bo.TenantId == 1);
            }
            catch (Exception ex)
            {
                ExceptionUtility.LogException(args.userId, ex);
            }
        }
        //-----------------------------------------------------------------------------------------
    }
}

GitHub drops “master” and “slave” terms amidst BLM backlash

Microsoft's GitHub is removing coding terms like 'master' and 'slave'

In my ANZ project of 500+ files I found 21 affected files. Required about 1 hour to replace all instances of "master" with alternative names.

Using CreationTime to order entities is the solution. Thank you.

I have the following code:

MyAppService.cs

        [AbpAuthorize(AppPermissions.Pages_QuestionBanks)]
        public async Task<PagedResultDto<QuestionBankDto>> GetAll(GetAllQuestionBanksInput input)
        {
            List<QuestionBankDto> questionBankList;
            int totalCount;

            try
            {
                using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.MayHaveTenant,
                                                       AbpDataFilters.MustHaveTenant,
                                                       AbpDataFilters.SoftDelete))
                {
                    var filteredQuestionBanks = _questionBankRepository.GetAll()
                        .WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => false || e.QuestionBankName.Contains(input.Filter));

                    var course_query = _courseRepository.GetAll();
                    var courses = course_query.ToList();

                    var questionBanks = from o in filteredQuestionBanks

                                        join o1 in _userRepository.GetAll() on o.CreatorUserId equals o1.Id into j1
                                        from s1 in j1.DefaultIfEmpty()

                                        join o2 in _courseRepository.GetAll() on o.CourseId equals o2.Id into j2
                                        from s2 in j2.DefaultIfEmpty()

                                        select new QuestionBankDto()
                                        {
                                            CreateTicks = o.CreationTime.Ticks,
                                            CreateTime = o.CreationTime.ToLocalTime().ToString(),
                                            QuestionsCount = o.QuestionsCount,
                                            Flags = o.Roster,
                                            IsSet = (long)o.IsSet_,
                                            QuestionBankName = o.QuestionBankName,
                                            UserName = s1.UserName,
                                            CourseName = s2.CourseName,
                                            Id = o.Id
                                        };

                    var pagedAndFilteredQuestionBanks = questionBanks
                        .OrderBy(input.Sorting ?? "id asc")
                        .PageBy(input)
                        ;

                    questionBankList = await pagedAndFilteredQuestionBanks.ToListAsync();

                    totalCount = questionBankList.Count();
                }

                return new PagedResultDto<QuestionBankDto>(
                    totalCount,
                    questionBankList
                );
            }
            catch (Exception ex)
            {
                ExceptionUtility.LogException(AbpSession.UserId, ex);
                return null;
            }
        }

QuestionBankDto.cs

using Abp.Application.Services.Dto;

namespace ngTTM.TtmDataModel.Dtos
{
    public class QuestionBankDto : EntityDto
    {
        public string UserName { get; set; }

        public string CourseName { get; set; }

        public string QuestionBankName { get; set; }

        public int QuestionsCount { get; set; }

        public string Flags { get; set; }

        public long IsSet { get; set; }

        public string CreateTime { get; set; }

        public long CreateTicks { get; set; }
    }

Where public class QuestionBank : AuditedEntity

The statement questionBankList = await pagedAndFilteredQuestionBanks.ToListAsync(); throws an error when input.Sorting is "createTicks ASC" or "createTicks DESC". All other fields sort without raising an Exception. Exception Detail:

7/30/2020 11:27:42 PM (PST)  
1
Message: 
Exception Type: System.InvalidOperationException
Exception: The LINQ expression 'OrderByDescending<TransparentIdentifier<TransparentIdentifier<QuestionBank, User>, Course>, long>(
    source: LeftJoin<TransparentIdentifier<QuestionBank, User>, Course, int, TransparentIdentifier<TransparentIdentifier<QuestionBank, User>, Course>>(
        outer: LeftJoin<QuestionBank, User, Nullable<long>, TransparentIdentifier<QuestionBank, User>>(
            outer: DbSet<QuestionBank>, 
            inner: Where<User>(
                source: DbSet<User>, 
                predicate: (u) => (Unhandled parameter: __ef_filter__p_0) || !(((ISoftDelete)u).IsDeleted) && (Unhandled parameter: __ef_filter__p_1) || ((IMayHaveTenant)u).TenantId == (Unhandled parameter: __ef_filter__CurrentTenantId_2)), 
            outerKeySelector: (q) => q.CreatorUserId, 
            innerKeySelector: (u) => (Nullable<long>)u.Id, 
            resultSelector: (q, u) => new TransparentIdentifier<QuestionBank, User>(
                Outer = q, 
                Inner = u
            )), 
        inner: Where<Course>(
            source: DbSet<Course>, 
            predicate: (c) => (Unhandled parameter: __ef_filter__p_3) || ((IMayHaveTenant)c).TenantId == (Unhandled parameter: __ef_filter__CurrentTenantId_4)), 
        outerKeySelector: (ti) => ti.Outer.CourseId, 
        innerKeySelector: (c) => c.Id, 
        resultSelector: (ti, c) => new TransparentIdentifier<TransparentIdentifier<QuestionBank, User>, Course>(
            Outer = ti, 
            Inner = c
        )), 
    keySelector: (ti0) => ti0.Outer.Outer.CreationTime.Ticks)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Source: Microsoft.EntityFrameworkCore
Stack Trace: 
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|8_0(ShapedQueryExpression translated, <>c__DisplayClass8_0& )
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.&lt;ExecuteAsync&gt;b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at ngTTM.TtmDataModel.QuestionBanksAppService.GetAll(GetAllQuestionBanksInput input) in C:\Users\Tim\Documents\__ngTTMv800\aspnet-core\src\ngTTM.Application\TtmDataModel\QuestionBanksAppService.cs:line 708

"CreationTime" field is displayed correctly for all other sort fields.

How can I sort on the "CreationTime" field?

Showing 121 to 130 of 398 entries