Why doesn't Azure load properly the Interop? - azure

I have a WebApp on Azure that uses a dll. This library needs Interop libraries x86 and x64.
Sometimes, at the restart of the App (I suppose), the App fails due to an exception:
System.EntryPointNotFoundException: Unable to find an entry point named 'sqlite3_config' in DLL 'SQLite.Interop.dll'. at System.Data.SQLite.UnsafeNativeMethods.sqlite3_config_none(SQLiteConfigOpsEnum op) at System.Data.SQLite.SQLite3.StaticIsInitialized() at System.Data.SQLite.SQLiteLog.Initialize() at System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework) at T_Dox.WebService.SQLiteDb.CreateConnection() at WebService.CeDb.Connect()
The SQLite used is the SQLCipher's one.
What am I missing here? I don't understand why the app stops working suddenly even if I don't make any changes.
The App is a Web Service (.asmx file) that uses a data access layer to perform some business logic.
It was under a web site project, then we moved it into another project, a webapi\mvc project.
The routing bypasses this extension, so it works as before, a simple web service call.
The called web method initializes a business class loaded from another .net library (a VB.Net library).
Inside, this class uses a wrapper to a sqlConnection, in this case the SQLiteConnection.
In its constructor it starts an SQLiteConnection, and normally it works.
Then it performs some CRUD operations ...
So I can represent the operation this way:
[WebService(Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SampleService : System.Web.Services.WebService
{
[WebMethod]
public ServerInfo Test()
{
var sampleBusinessClass = new SampleBusinessCLass();
sampleBusinessClass.DoSomething();
using(var connection = new SQLiteConnection()) //the constructor is the parameterless one
{
//...
}
}
}
And the stack will be this (this is not the real one):
System.EntryPointNotFoundException: Unable to find an entry point named 'sqlite3_config' in DLL 'SQLite.Interop.dll'.
at System.Data.SQLite.UnsafeNativeMethods.sqlite3_config_none(SQLiteConfigOpsEnum op)
at System.Data.SQLite.SQLite3.StaticIsInitialized()
at System.Data.SQLite.SQLiteLog.Initialize()
at System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework)
at xxx.WebService.SampleService.Test()
It always works, but sometimes it starts to launch this error until the stop and start of the web application on iss (in our case: Azure).
Inspecting the System.Data.SQlite.dll I can clearly see the entry point and actually it always passes this internal code (no conditions that can bypass this part) and it generally works.
The System.Data.SQlite.dll (1.0.96.0 version) is provided by SqlCypher product. I think it is the original System.Data.SQLite one because at first sight I can see the same assembly manifest and content.
The interop System.Data.SQLite uses is probably modified by SqlCypher team to give their features.
To avoid possible issues we put the interop in the path /bin/x64, then we compile our web app ONLY in x64 and it runs on a x64 environment.

Related

Blazor Component (in library) and JSInterop

I've created a Blazor Component within a full Blazor project and all works well.
However, when I move this component to it's own Razor Class Library project, I am now getting an error that I cannot use JSInterop until a connection with the server is made. I am running my code in the OnAfterRenderAsync() method.
I had to alter the code a little when I made the change.
In a full Blazor project, JSInterop is provided for you with DI in the Startup class. But this is not the case with a calss library.
So instead of "#inject JSInterop js" in the page, I had to set it up like this -
private IJSRuntime js { get; set; }
protected override void OnInitialized()
{
js = ScopedServices.GetRequiredService<IJSRuntime>();
}
From the sketchy details available on the web, I'm assuming this gets the service from the Parent project.
Using debugging, I can see that js is NOT null. It does seem to have been set to a valid object.
Can anyone point me in the right direction?
The server pre-renders, so your code will run before there is a client connection to the server. When rendering in OnAfterRenderAsync you should only use IJSRuntime when the firstRender parameter is true, or any point after that, but never before.
Found the solution to my problem and it has rendered my initial question irrelevant.
When I copied my component to it's own class library project, it would not compile. It gave me an error on the line #inject JSInterop js.
This led me to believe that it didn't know how to inject this as it is not set during the Startup of the project, as it is in a Blazor app.
So I cobbled together the code to get a reference via ScopedServices.GetRequiredService().
This did create an object but did not have _clientProxy set which contains the connection to the server.
So digging round I managed to find a complete component library example project at BlazorHelp Website
This did have the JSInterop injected in the Blazor file. So I reverted my code back to the original code that worked in the full project and tried to compile. It gave me the same error. So I deleted the #inject JSInterop js line and typed it in again.
IT RECOGNIZED IT!!!
It still failed to compile, not recognizing a custom type (Pivot) and asking whether I had included a reference to it.
[CascadingParameter] public Pivot OwnerPivot { get; set; }
I deleted the word Pivot and retyped it and, voila, it compiled.
So it looks like there some sort of error in VS2019 or the razor compiler, where deleting code in the source file and re-entering caused it to recognize and compile.

Why my custom C# extention does not execute when deployed to Spotfire WebPlauer/Consumer

I have a simple custom Add-in that just displays a message to the user.
namespace GeorgiSpotfireCustomExtention
{
public class GeorgiEvent : CustomApplicationEventHandler
{
protected override void OnApplicationInstanceCreated(AnalysisApplication application)
{
base.OnApplicationInstanceCreated(application);
MessageBox.Show("On Application Instance Created");
}
}
}
That is my CustomAddIn class:
public sealed class CustomAddIn : AddIn
{
// Override methods in this class to register your extensions.
protected override void RegisterApplicationEventHandlers(ApplicationEventHandlerRegistrar registrar)
{
base.RegisterApplicationEventHandlers(registrar);
registrar.Register(new GeorgiEvent());
}
}
I am just trying to learn the package deployment process. When I am running it locally - in the installed Spotfire Analyst client it displays the message just fine:
However, when I package the extention, add it to the server (via the "Deployments & Packages" section, adding the "spk" file and then saving the area, the message is not shown when I try to open a document in the WebPlayer/Consumer.
Notes: I am choosing "TIBCO Spotfire Any Client" for my intended client in the Package Builder when building the spk file.
from the Spotfire Wiki (emphasis mine):
WinForms graphical user interface is a component of the .NET Framework and not something supplied by Tibco Spotfire. It's not recommended to implement solutions using Forms, but sometimes it could be handy when debugging. There is no commitment that it will work in future versions of the Analyst client. Forms are not supported on the Web Player.
the example listed on the wiki is for IronPython, but presumably the same holds true for C# extensions.
Correct. My assumption, and I don’t really know a lot about .NET, so this is not absolute, is that the form is rendered on the machine executing the code. In the case of your example above, the dialog would pop on the Node Manager host. If you’re really set on using an alert like this, you can accomplish it in JavaScript with an ‘alert()’. There is probably a way to render dialogues o in the web client too, but I don’t know it offhand.

Unable to find assembly on Azure Mobile Service

I have an Azure Mobile Service project which has a dependency to another (persistence) project which is referencing FluentNHibernate. Locally everything is running correctly in Release and Debug mode. Publishing the project seems to be successful (blue smiley). The problems starts when I make a request, where FluentNHibernate is used. I get the following error message:
Unable to find assembly 'FluentNHibernate, Version=2.0.3.0, Culture=neutral, PublicKeyToken=null'.
I already tried a lot of things:
Reinstalling packages
A new plain vanilla Mobile Service
Adding dependentAssembly in Web.config in the main project and App.config in the persistence project.
A little confusing for me is following fact: When I change the version of the FluentNHibernate package, I can see in the publish preview window that this dll will not be updated.
I am really not sure if this problem is depended to this specific package (FluentNHibernate). For example, what means: PublicKeyToken=null?
What else can I try to make the service running in the cloud?
The code below worked for my solution. It wires up a handler to the AppDomain's AssemblyResolve event, which is raised if an assembly cannot be found. In this case, I tell it to check the currently loaded assemblies and return one if there is a match, which there should be for FluentNHibernate. Try sticking this as the first line in WebApiConfig.Register
public static void Register()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
return AppDomain.CurrentDomain.GetAssemblies()
.Where(a => a.FullName == args.Name).FirstOrDefault();
};
// the rest of WebApiConfig.Register...
}

autofac and multithreading

when doing parallel/multithreading, if there are dependencies that are not thread safe, what kind of instance method can be used with autofac to get an instance per thread? from what I know, autofac is the kind of DI container for certain framework like asp.net/mvc but for the rest of the app type like windows service, it does not have any support. in my scenario, i am doing multithreading for a windows service that also hosting a web api service. what kind of registration can be used so that it will work for web api instanceperhttprequest and instanceperlifetimescope. two separate container?
EDIt:
using this parallel extension method here:
public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate
{
using (partition)
{
while (partition.MoveNext())
{
await body(partition.Current);
}
}
}));
}
so the body will be use to do the work. DI will need to be inside of the body func.
It doesn't matter what kind of application you run; the pattern is always the same. You should resolve one object graph per request. In a web application, a request means a web request, in a windows service, a request is usually a timer pulse.
So in a windows service, each 'pulse' you start a new lifetime scope, and within this scope you resolve your root object and call it.
If however, you process items in parallel within a single request, you should see each processed item as a request of its own. So that means that on each thread you should start a new lifetime scope and resolve a sub object graph from that scope and execute that. Prevent passing services that are resolved from your container, from thread to thread. This scatters the knowledge of what is thread-safe, and what isn't throughout the application, instead of keeping that knowledge centralized in the startup path of your application where you compose your object graphs (the composition root).
Take a look at this article about working with dependency injection in multi-threaded applications. It's written for a different DI library, but you'll find most of the advice generically applicable to all DI libraries.

Add WebRole.cs - and have it called - in an existing ASP.NET MVC site converted to web role

I have an ASP.NET MVC 4 site running perfectly well in an Azure WebRole. The ASP.NET MVC project was started on its own, after which I added an Azure Cloud Service project to the solution and added the ASP.NET project/site as one of the 'roles' of the service (so it shows up in the 'Roles' folder).
My problem is that I would like to have working a WebRole.cs file within the ASP.NET MVC project, but no matter what I've tried to do, it appears that when deployed, it just never gets called. OnStart and the override of Run (which I know, must never leave the loop) -- these just apparently never get called.
But if you startup a new CloudService project and add, at that time from the start, an ASP.NET MVC project, it automatically has a WebRole.cs file in it, so my guess is that I need to configure something somewhere for the WebRole.cs (actually speaking, the WebRole class, which inherits RoleEntryPoint) to get called. What might that be?
using System;
using System.Web;
//using Microsoft.WindowsAzure.StorageClient;
using System.Diagnostics;
using System.Threading;
namespace Us.WebUI
{
public class WebRole : Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint
{
public override bool OnStart()
{
return true; //return base.OnStart(); // CALL THIS???
}
public override void Run()
{
while (true) {
Thread.Sleep(TimeSpan.FromSeconds(30));
try {
EmailFuncs.SendEmailToUs("An email from our WebRole?????", "Email me this, email me that.");
}
catch { }
}
}
}
}
UPDATE: Thanks, the question has been answered. But I will add: On doing this, while it clearly was working (fully deployed and in emulator), that suddenly I was having problems doing a full publish of the site. After a azure publish took 3 hours:
Verifying storage account 'xyz'... > Uploading Package... > - Updating... [stayed here for 3 hours], it failed with this error: The server encountered an internal error. Please retry the request. So one thing I was wondering is, did I need to override OnStop in WebRole.cs?
UPDATE 2: Those previous problems were fixed, and had nothing to do with this issue. Actually, I've learned this: If you ever have any warnings generated in your build, Azure often will not work with them even when they don't cause problems locally or in other hosts. Since then, I've been much more studious to tackling build warnings (but critical to this is turning off with warning codes the many warning types you want to ignore!).
Adding a class to your Web Project which inherits from RoleEntryPoint is sufficient, it should just work. Did you try setting a breakpoint in the emulator?
What you might be experiencing is that EmailFuncs.SendEmailToUs requires info from the app/web.config and that this info is not available. You need to know that your WebRole class runs in a different process (not your web application), meaning it's not using your web.config. If you want the WebRole.cs to read info from the configuration file, you'll need to add these settings in WaIISHost.exe.config

Resources