AvaloniaUI: Setup was already called on one of AppBuilder instances - avaloniaui

Whenever I try to restart Avalonia application form base application, I get an exception: "Setup was already called on one of AppBuilder instances." on SetupWithLifetime() call.
Application Startup code is:
public static void Start()
{
lifeTime = new ClassicDesktopStyleApplicationLifetime()
{
ShutdownMode = ShutdownMode.OnLastWindowClose
};
BuildAvaloniaApp().SetupWithLifetime(lifeTime);
lifeTime.Start(new[] { "" });
}
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
Application shutdown code is:
lifeTime.Shutdown();
lifeTime.Dispose();
Here's a link to functional example code, which produces this error: https://pastebin.com/J1jqppPv
Has anyone encountered such problem? Thank you

SetupWithLifetime calls Setup which can only be called once. A possible solution is to call SetupWithoutStarting on BuildAvaloniaApp, which can only be called once as well, for example:
private static AppBuilder s_builder;
static void Main(string[] args)
{
s_builder = BuildAvaloniaApp();
}
public static void Start()
{
lifeTime = new ClassicDesktopStyleApplicationLifetime()
{
ShutdownMode = ShutdownMode.OnLastWindowClose
};
s_builder.Instance.Lifetime = lifeTime;
s_builder.Instance.OnFrameworkInitializationCompleted();
lifeTime.Start(new[] { "" });
}
private static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
Additional note: Restarting the app probably won't work on macOS.

Related

Is it possible to add completion items to a Microsoft Language Server in runtime?

I am trying to develop a IntelliJ plugin which provides a Language Server with help of lsp4intellij by ballerina.
Thing is, i've got a special condition: The list of completion items should be editable in runtime.
But I've not found any way to communicate new completionItems to the LanguageServer process once its running.
My current idea is to add an action to the plugin which builds a new jar and then restarts the server with the new jar, using the Java Compiler API.
The problem with that is, i need to get the source code from the plugin project including the gradle dependencies accessable from the running plugin... any ideas?
If your requirement is to modify the completion items (coming from the language server) before displaying them in the IntelliJ UI, you can do that by implementing the LSP4IntelliJ's
LSPExtensionManager in your plugin.
Currently, we do not have proper documentation for the LSP4IntelliJ's extension points but you can refer to our Ballerina IntelliJ plugin as a reference implementation, where it has implemented Ballerina LSP Extension manager to override/modify completion items at the client runtime in here.
For those who might stumble upon this - it is indeed possible to change the amount of CompletionItems the LanguageServer can provide during runtime.
I simply edited the TextDocumentService.java (the library I used is LSP4J).
It works like this:
The main function of the LanguageServer needs to be started with an additional argument, which is the path to the config file in which you define the CompletionItems.
Being called from LSP4IntelliJ it would look like this:
String[] command = new String[]{"java", "-jar",
"path\\to\\LangServer.jar", "path\\to\\config.json"};
IntellijLanguageClient.addServerDefinition(new RawCommandServerDefinition("md,java", command));
The path String will then be passed through to the Constructor of your CustomTextDocumentServer.java, which will parse the config.json in a new Timer thread.
An Example:
public class CustomTextDocumentService implements TextDocumentService {
private List<CompletionItem> providedItems;
private String pathToConfig;
public CustomTextDocumentService(String pathToConfig) {
this.pathToConfig = pathToConfig;
Timer timer = new Timer();
timer.schedule(new ReloadCompletionItemsTask(), 0, 10000);
loadCompletionItems();
}
#Override
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(CompletionParams completionParams) {
return CompletableFuture.supplyAsync(() -> {
List<CompletionItem> completionItems;
completionItems = this.providedItems;
// Return the list of completion items.
return Either.forLeft(completionItems);
});
}
#Override
public void didOpen(DidOpenTextDocumentParams didOpenTextDocumentParams) {
}
#Override
public void didChange(DidChangeTextDocumentParams didChangeTextDocumentParams) {
}
#Override
public void didClose(DidCloseTextDocumentParams didCloseTextDocumentParams) {
}
#Override
public void didSave(DidSaveTextDocumentParams didSaveTextDocumentParams) {
}
private void loadCompletionItems() {
providedItems = new ArrayList<>();
CustomParser = new CustomParser(pathToConfig);
ArrayList<String> variables = customParser.getTheParsedItems();
for(String variable : variables) {
String itemTxt = "$" + variable + "$";
CompletionItem completionItem = new CompletionItem();
completionItem.setInsertText(itemTxt);
completionItem.setLabel(itemTxt);
completionItem.setKind(CompletionItemKind.Snippet);
completionItem.setDetail("CompletionItem");
providedItems.add(completionItem);
}
}
class ReloadCompletionItemsTask extends TimerTask {
#Override
public void run() {
loadCompletionItems();
}
}
}

Toggling App.Config settings at runtime C#

I am wondering what the best approach to toggling App.Config settings for C# would be. This is involving our test suite, and we would like the option to either choose a remote or local environment to kick the tests off. We use LeanFT and NUnit as our testing framework, and currently in order to get tests to run remote we have to add an <leanft></leanft> config in the App.config file. How can I specify different configurations at run time when I kick these tests off thru the command line? Thanks!
Any leanft configuration can be modified at runtime, by using the SDK namespace or the Report namespace.
Here's an example using NUnit 3 showing how you can achieve this
using NUnit.Framework;
using HP.LFT.SDK;
using HP.LFT.Report;
using System;
namespace LeanFtTestProject
{
[TestFixture]
public class LeanFtTest
{
[OneTimeSetUp]
public void TestFixtureSetUp()
{
// Initialize the SDK
SDK.Init(new SdkConfiguration()
{
AutoLaunch = true,
ConnectTimeoutSeconds = 20,
Mode = SDKMode.Replay,
ResponseTimeoutSeconds = 20,
ServerAddress = new Uri("ws://127.0.0.1:5095") // local or remote, decide at runtime
});
// Initialize the Reporter (if you want to use it, ofc)
Reporter.Init(new ReportConfiguration()
{
Title = "The Report title",
Description = "The report description",
ReportFolder = "RunResults",
IsOverrideExisting = true,
TargetDirectory = "", // which means the current parent directory
ReportLevel = ReportLevel.All,
SnapshotsLevel = CaptureLevel.All
});
}
[SetUp]
public void SetUp()
{
// Before each test
}
[Test]
public void Test()
{
Reporter.ReportEvent("Doing something", "Description");
}
[TearDown]
public void TearDown()
{
// Clean up after each test
}
[OneTimeTearDown]
public void TestFixtureTearDown()
{
// If you used the reporter, invoke this at the end of the tests
Reporter.GenerateReport();
// And perform this cleanup as the last leanft step
SDK.Cleanup();
}
}
}

Mockito.doNothing() is still running

I'm trying to test small pieces of code. I do not want test one of the method and used Mockito.doNothing(), but this method was still run. How can I do that?
protected EncoderClientCommandEventHandler clientCommandEventHandlerProcessStop = new EncoderClientCommand.EncoderClientCommandEventHandler() {
#Override
public void onCommandPerformed(
EncoderClientCommand clientCommand) {
setWatcherActivated(false);
buttonsBackToNormal();
}
};
protected void processStop() {
EncoderServerCommand serverCommand = new EncoderServerCommand();
serverCommand.setAction(EncoderAction.STOP);
checkAndSetExtension();
serverCommand.setKey(getArchiveJobKey());
getCommandFacade().performCommand(
serverCommand,
EncoderClientCommand.getType(),
clientCommandEventHandlerProcessStop);
}
#Test
public void testClientCommandEventHandlerProcessStop() {
EncoderClientCommand encoderClientCommand = mock(EncoderClientCommand.class);
Mockito.doNothing().when(encoderCompositeSpy).buttonsBackToNormal();
when(encoderCompositeSpy.isWatcherActivated()).thenReturn(false);
encoderCompositeSpy.clientCommandEventHandlerProcessStop.onCommandPerformed(encoderClientCommand);
I've found the problem. One of the variable is already mocked in buttonsBackNormal().

NancyFx Authentication per Route

From what I saw in the source code RequiresAuthentication() does an Authentication check for the whole module. Is there any way to do this per Route?
I had the same problem. However it turns out the RequiresAuthentication works at both the module level and the route level. To demonstrate, here is some code ripped out my current project (not all routes shown for brevity).
public class RegisterModule : _BaseModule
{
public RegisterModule() : base("/register")
{
Get["/basic-details"] = _ => View["RegisterBasicDetailsView", Model];
Get["/select"] = _ =>
{
this.RequiresAuthentication();
return View["RegisterSelectView", Model];
};
}
}
Of course the only problem with doing it this way is that all the protected routes in the module need to call RequiresAuthentication. In the case of my module above, I have another 5 routes (not shown) all of which need protecting, so that makes six calls to RequiresAuthentication instead of one at the module level. The alternative would be to pull the unprotected route into another module, but my judgement was that a proliferation of modules is worse than the additional RequiresAuthentication calls.
namespace Kallist.Modules {
#region Namespaces
using System;
using Nancy;
#endregion
public static class ModuleExtensions {
#region Methods
public static Response WithAuthentication(this NancyModule module, Func<Response> executeAuthenticated) {
if ((module.Context.CurrentUser != null) && !string.IsNullOrWhiteSpace(module.Context.CurrentUser.UserName)) {
return executeAuthenticated();
}
return new Response { StatusCode = HttpStatusCode.Unauthorized };
}
#endregion
}
}
I ran into the same issue, here's how I solved it.
var module = new MyModule();
module.AddBeforeHookOrExecute(context => null, "Requires Authentication");
_browser = new Browser(with =>
{
with.Module(module);
with.RequestStartup((container, pipelines, ctx) =>
{
ctx.CurrentUser = new User { UserId = "1234", UserName = "test"};
});
});
I can now use this.RequiresAuthentication() at the module level and run my unit tests.

New MVC 4 Beta Web API is not serving requests when ran as a Windows Service

I'm trying to run a self hosted executable as a Windows service. I'm using the MVC 4 beta Web API. First I used Derik Whittaker's blog for setting up the basic console application and tested it with positive results.
I then used Einar Egilsson's blog to make it work as both a console application and a windows service. The application installed as a service just fine. I set the service logon to use my own for this basic testing; it failed to bind to the socket without this. When the service starts up I see all my trace logs as expected there are no fatal errors. The application appears to be running normally. When I test using fiddler using the same request for the console application I get a "HTTP/1.1 500 Internal Server Error".
Using this same code when I turn off the service then launch using F5 in VS the application starts up just fine and serves the same request!? The log entries are identical within the same execution paths.
public partial class TestService : ServiceBase {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private HttpSelfHostServer _server;
static void Main(string[] args) {
Logger.Debug("Main Called");
var service = new TestService();
if (Environment.UserInteractive) {
Logger.Debug("Environment.UserInteractive == true");
Console.WriteLine("Press any key to stop program");
service.OnStart(args);
service.OnStop();
} else {
Logger.Debug("Environment.UserInteractive == false");
try {
Run(service);
} catch(Exception exception) {
Logger.Fatal(exception.Message, exception);
}
}
}
protected override void OnStart(string[] args) {
Logger.Debug("OnStart called");
var hostUri = string.Format("http://{0}:{1}", Environment.MachineName, ConfigurationManager.AppSettings["Service.Port"]);
Logger.Debug("URL:" + hostUri);
var selfHostConfiguration = new HttpSelfHostConfiguration(hostUri);
selfHostConfiguration.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: "endpoints/{controller}",
defaults: null
);
Logger.Debug("Routes registered");
try {
using (_server = new HttpSelfHostServer(selfHostConfiguration)) {
Logger.Debug("Hosting at " + hostUri + "/endpoints/{controller}");
_server.OpenAsync().Wait();
if (Environment.UserInteractive) { // *** I've tried this commented out as well
Console.ReadLine();
}
Logger.Debug("End of using");
}
} catch(Exception exception) {
Logger.Fatal(exception.Message, exception);
if(exception.InnerException != null) {
Logger.Fatal(exception.InnerException.Message, exception.InnerException);
}
}
}
protected override void OnStop() {
_server.Dispose();
}
}
It has been some time since you posted this but I wanted to input.
I don't know why this is, but the internal error comes from initializing the self host inside the onStart method. You must initialize it in the constructor of the service and then only call the _server.OpenAsync() in the onStart method.
Or at least that is what worked for me.
Use TopShelf. I just blogged about how to do that.
as i can see, you use _server.OpenAsync().Wait(); in OnStart method. This just makes your initialization code to freeze, all code after that line will not execute. To avoid this try to remove .Wait() from the OpenAsync().