eXpand
eXpand copied to clipboard
JobScheduler.Hangfire Application Error opening Dashboard
In development mode, when I select a Worker and open dashboard i got the following error, but the dashboard is opened in new tab. In production, the dashboard is not opened,
The error occurred:
Type: JSException
Message: Converting circular structure to JSON
--> starting at object with constructor 'Window'
--- property 'window' closes the circle
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Window'
--- property 'window' closes the circle
at JSON.stringify (
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args) InnerException is null
please post a sample and details on how to repro this
Hi, I just select one worker from job and then click on the Dashboard button. record.zip
The issues seems related to invocation "JsRuntime.InvokeAsync(" instead "JsRuntime.InvokeVoidAsync("
did you tried to upgrade the hangfire libs to a newer version to see if they resolved it?
I found the problem in your code on the class Xpand.XAF.Modules.JobScheduler.Hangfire.JobSchedulerService, method JobDashboard.
The return code, should be:
return args.SelectedObjects.Cast<JobWorker>().ToObservable(ImmediateScheduler.Instance) .Select(job => jsRuntime?.InvokeVoidAsync("open", $"{uri}{job.Id}", "_blank").AsTask());
Could you confirm, please? It worked for me, but I prefer to reference the Nuggets.
I recently switched the JobScheduler tests to integration tests, for testing the actual app instead of a SUT system, however yet no test for Dashboard. I will add one when my time permits for now your observation looks correct, I will update the source code.
Feel free to send a PR when ever u have any fix that was a nice catch
I do not see how it worked for you as it does not even compile unless you posted a wronf snippet. Without testing the correct version should be
args.SelectedObjects.Cast<JobWorker>().ToNowObservable()
.SelectMany(job => Observable.FromAsync(() => jsRuntime?.InvokeVoidAsync("open", [$"{uri}{job.Id}", "_blank"]).AsTask()))
can u please test is fine so I can send a build?
Should be Select instead SelectMany, SelectMany is for relations n to n, which is not the case :
return args.SelectedObjects.Cast<JobWorker>().ToObservable(ImmediateScheduler.Instance).Select(job => jsRuntime?.InvokeVoidAsync("open", $"{uri}{job.Id}", "_blank").AsTask());
your answer beats me, can you explain why you think the Task should not be flattened?
The SelectMany
is the operator that flattens the inner observable which in this case is the task. Although this task is executed on creation so it worked as you mentioned with the Select
is not the correct approach and probably the ToUnit
hide it from you.
IObservable<IObservable<Unit>> observable = e.SelectedObjects.Cast<JobWorker>().ToNowObservable()
.Select(job => jsRuntime?.InvokeVoidAsync("open", [$"{uri}{job.Id}", "_blank"]).AsTask().ToObservable());
the Select
will project the Task to IObservable<IObservable<Unit>>
where the SelectMany
will flatten it
IObservable<Unit> observable = e.SelectedObjects.Cast<JobWorker>().ToNowObservable()
.SelectMany(job => jsRuntime?.InvokeVoidAsync("open", [$"{uri}{job.Id}", "_blank"]).AsTask().ToObservable());
Ok, maybe I'm not seeing the whole concept here. I'm used to LINQ and I use SelectMany() to collapse a multidimensional sequence in a way that would otherwise require a second Select() or loop. In this case, i thought we just want to select the JobWorker Id's in a simple one-to-one projection, and foreach one create create a task.
I use SelectMany() to collapse a multidimensional sequence
it is LINQ and it is as you said it now else flattening and our return is a Unit not a worker. A Unit is a type we use to merge all observables into a signle subscription
.Merge(manager.TriggerJobsFromAction())
.Merge(manager.PauseJobsFromAction())
.Merge(manager.ResumeJobsFromAction())
.Merge(manager.JobDashboard())
all this methods same for LINQ must have the same type in order to operate on them (Merge, Concat etc) so we use the Unit, the ToUnit method is a convenient extension that projects any type however if you not carefull it hides the whole picture from you
public static IObservable<Unit> ToUnit<T>(this IObservable<T> source)
=> source.Select(_ => Unit.Default);
Ok, thanks for the clarification. What is the expected behaviour, o new dashboard tab shoud be opened for each selected Worker? I selected multiple Workers, but only one tab is opened.
The pre-release 4.232.2.0 in the Reactive.XAF lab
branch includes commits that relate to this task:
- [JobScheduler.Hangfire Application Error opening Dashboard
#1028](https://github.com/eXpandFramework/Reactive.XAF/commit/663345a48fec111b62b6a6649ddb504c3646acdc)
To minimize version conflicts we recommend that you use the Xpand.XAF.Core.All, Xpand.XAF.Win.All, Xpand.XAF.Web.All packages. Doing so, all packages will be at your disposal and .NET will add a dependecy only to those packages that you actually use and not to all (see the Modules installation-registrations youtube video).
Released packages:
Xpand.Extensions v.4.232.2 Xpand.Extensions.Blazor v.4.232.2 Xpand.Extensions.Mono.Cecil v.4.232.2 Xpand.Extensions.Office.Cloud v.4.232.2 Xpand.Extensions.Office.Cloud.Google.Blazor v.4.232.2 Xpand.Extensions.Reactive v.4.232.2 Xpand.Extensions.XAF v.4.232.2 Xpand.Extensions.XAF.Xpo v.4.232.2 Xpand.TestsLib v.4.232.2 Xpand.TestsLib.Blazor v.4.232.2 Xpand.TestsLib.Common v.4.232.2 Xpand.TestsLib.EasyTest v.4.232.2 Xpand.VersionConverter v.4.232.2 Xpand.XAF.Core.All v.4.232.2 Xpand.XAF.Modules.AutoCommit v.4.232.2 Xpand.XAF.Modules.Blazor v.4.232.2 Xpand.XAF.Modules.BulkObjectUpdate v.4.232.2 Xpand.XAF.Modules.CloneMemberValue v.4.232.2 Xpand.XAF.Modules.CloneModelView v.4.232.2 Xpand.XAF.Modules.Email v.4.232.2 Xpand.XAF.Modules.GridListEditor v.4.232.2 Xpand.XAF.Modules.HideToolBar v.4.232.2 Xpand.XAF.Modules.JobScheduler.Hangfire v.4.232.2 Xpand.XAF.Modules.JobScheduler.Notification v.4.232.2 Xpand.XAF.Modules.MasterDetail v.4.232.2 Xpand.XAF.Modules.ModelMapper v.4.232.2 Xpand.XAF.Modules.ModelViewInheritance v.4.232.2 Xpand.XAF.Modules.Office.Cloud.Google v.4.232.2 Xpand.XAF.Modules.Office.Cloud.Google.Calendar v.4.232.2 Xpand.XAF.Modules.Office.Cloud.Google.Tasks v.4.232.2 Xpand.XAF.Modules.Office.DocumentStyleManager v.4.232.2 Xpand.XAF.Modules.OneView v.4.232.2 Xpand.XAF.Modules.PositionInListView v.4.232.2 Xpand.XAF.Modules.ProgressBarViewItem v.4.232.2 Xpand.XAF.Modules.RazorView v.4.232.2 Xpand.XAF.Modules.Reactive v.4.232.2 Xpand.XAF.Modules.Reactive.Logger v.4.232.2 Xpand.XAF.Modules.Reactive.Logger.Client.Win v.4.232.2 Xpand.XAF.Modules.Reactive.Logger.Hub v.4.232.2 Xpand.XAF.Modules.Reactive.Rest v.4.232.2 Xpand.XAF.Modules.RefreshView v.4.232.2 Xpand.XAF.Modules.SequenceGenerator v.4.232.2 Xpand.XAF.Modules.Speech v.4.232.2 Xpand.XAF.Modules.SpellChecker v.4.232.2 Xpand.XAF.Modules.StoreToDisk v.4.232.2 Xpand.XAF.Modules.SuppressConfirmation v.4.232.2 Xpand.XAF.Modules.TenantManager v.4.232.2 Xpand.XAF.Modules.ViewEditMode v.4.232.2 Xpand.XAF.Modules.ViewItemValue v.4.232.2 Xpand.XAF.Modules.ViewWizard v.4.232.2 Xpand.XAF.Modules.Windows v.4.232.2 Xpand.XAF.Web.All v.4.232.2 Xpand.XAF.Win.All v.4.232.2Please update the related Nuget packages and test if issues is addressed. These are nightly nuget packages available only from our NugetServer.
If you do not use these packages directly but through a module of the main eXpandFramework project, please wait for the bot to notify you again when integration is finished or update the related packages manually.
Thanks a lot for your contribution.
from the RX side we expect a task for each selected object to run
jsRuntime?.InvokeVoidAsync("open", [$"{uri}{job.Id}", "_blank"]).AsTask().ToObservable()
if u want to debug i suggest u verify if they open one by one so to have 2 tabs open at the end, so is it the browser that does not allow multiple popups in very close interval? then maybe a StepInterval
operator can help and so on..
or a SelectManySequential
operator instead of SelectMany
to flatten the task
Thank you very much. When new nuggets will be released?
nugets are already in the lab server, aren't they good enough at least for testing?
sure, I need to add a new package souce to reference them?
strange you can recompile/modify the source and you not aware of the readme? :)
did you by any chance find the time to experiement with my last suggestions? SelectManySequential + StepInterval
The browser was blocking multiple popups, so it's ok as it is. I don't know how to specify the stepinterval, but the SelectManySequential also works.
I'm using Hangfire because Windows Workflow Foundation is no longer supported in the new . NET 8. What is the purpose of the JobScheduler Notification Module?
do u mean that it does not work with SelectMany but works with the SelectManaySequential?
work in both ways
return e.SelectedObjects.Cast<JobWorker>().ToNowObservable()
.StepInterval(1.Seconds())
.SelectManySequential(job => jsRuntime?.InvokeVoidAsync("open", [$"{uri}{job.Id}", "_blank"]).AsTask().ToObservable());
you can add StepInterval just b4 the inner observable what that means is that it will wait for 1 second then it will open the page and it will wait for the task to complete (that's why we flatten) b4 moving to the next item
Closing issue for age. Feel free to reopen it at any time.
.Thank you for your contribution.