I got a pretty small Verticle that should connect to a database and regularly poll a table and send the objects to the event bus. Thus far I can connect to the database, but the handler afterwards gets not executed and my polling timer does not start. I guess it's something obvious and appreciate every help.
I use Vert.x 3.8 Promises as Futures are deprecated (just like in the example behind that link). As you can see in my code, using deprecated Futures works just fine! But who want's to use deprecated code, heh? Either I'm doing something wrong or that's a bug in Vert.x, what I don't assume.
My Vert.x is at 3.8.1
class JdbcVerticle extends AbstractVerticle {
private SQLConnection connection
#Override
void start(Promise<Void> startPromise) {
def jdbcParams = config().getJsonObject('connection')
// This gets executed:
testFuture().handler = { println "Test Future handler runs!" }
// This is never executed :-(
connect(jdbcParams).handler = { println "Connected..." }
}
Future<Void> connect(JsonObject jdbcParams) {
def promise = Promise.<Void>promise()
def client = JDBCClient.createShared(vertx, jdbcParams)
client.getConnection() { connection ->
if(connection.failed()) {
promise.fail(connection.cause())
} else {
this.connection = connection.result()
promise.complete()
}
}
return promise.future()
}
Future<Void> testFuture() {
def future = Future.<Void>future()
vertx.setTimer(200) { future.complete() }
return future
}
}
Related
I have method in class MyClassB which is triggered asynchronously from a method of MyClassA:
public void getProductCall()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
productRequest = service.createS4ProductRequest(getRepriceItems());
//Below is a rest call to another system
String response = pricing.getS4ProductResponse(quote.getAssetQuoteNrAndVrsn(), productRequest);
//I'm using the below 2 lines to check from ClassA's method to see if this process has ended
setProductResponse(response);
productPriceProcessEnded=true;
} catch (Exception e) {
productPriceErrorOccured=true;
e.printStackTrace();
}
}
}).start();
}
This is the piece of code in MyClassA i used to check if the above method is complete.
for(int i=0;i<1000000000;i++)
{
if(!networkAsynCalls.isListPriceErrorOccured())
{
if(networkAsynCalls.isListPriceprocessEnded())
{
return networkAsynCalls.getListReponse();
}
else
{
Thread.sleep(250);
continue;
}
}
else
return null;
}
instead of using this random for loop can i use some inbuilt method or service pool or something ?
Because,
1) This thread on method is in another class
2) In class MyClassB i have few more methods like this, so i need to check the status of all the methods in MyClassA
Thanks for any help.
If I undestand what you're trying to do is dispatch some code to be ran asynchronously, then be able to wait until it is completed (successfully or failed). If that's the case, you should take a look at Futures.
Here is an example based on the Javadoc:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
// do stuff
return "result";
}});
This code creates an object "future" that can be invoked to execute searcher.search(target). At this point, the code is not executed at all. You simply have an object representing a computation that may be executed asynchronously. To do so, you'd call:
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(future);
This snippet created an Executor (which is a fixed pool of 5 threads), then handed over the future to it for execution. The executor will run the computation from Future asynchronously.
Future offers some methods (see the Javadoc) to wait until completion, cancel, check completion status, etc. For example,
String result = future.get();
will block, waiting for the result indefinitely. A get(10, TimeUnit.SECONDS) will wait for 10 seconds and if the future has not completed, throw.
Good day everyone,
I'm creating a chatbot for my company and I started with the samples on github and the framework docs.
We decided to host it on Azure and added LUIS and Table Storage to it. The Bot runs fine locally in Botframework Emulator, but on Azure (WebChat, Telegram) it will only run for approximatly an hour to an hour and fifteen minutes, if no one tries to communicate with the bot. After this period of time, the bot will just run into an internal server error. When you ask the bot something, you can stretch this time window (For how long I don't know and why I don't know either, sorry).
In Azure "Always On" is set to true.
I'm really frustrated at this point, because I cannot find the problem and I'm pretty sure there must be something wrong with my code, because I don't properly understand the framework. I'm still a beginner with Azure, C# and Bot Framework.
Also I have already read everything on "internal server error's" on here and github. Also tried Debugging, even with extra Debbug options in VS. We have not tried Application Insights yet.
At the moment I'm doing everything with the LUIS Dialog which calls / Forwards to other IDialogs:
[LuisIntent(Intent_Existens)]
public async Task ExistensOf(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
{
var existens = new ExistensDialog();
var messageToForward = await message;
if (result.Entities.Count == 1)
{
messageToForward.Value = result.Entities[0].Entity;
await context.Forward(existens, AfterDialog, messageToForward);
}
else
{
context.Wait(this.MessageReceived);
}
}
I know that "Value" is for CardActions, but I don't know how else I could pass Entities to the child dialog.
[Serializable]
public class ExistensDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (message.Text.Contains("specificWord"))
{
await context.Forward(new ExistensHU(), AfterDialog, message);
}
else
{
await context.Forward(new ExistensBin(), AfterDialog, message);
}
}
private async Task AfterDialog(IDialogContext context, IAwaitable<object> result)
{
context.Done<object>(null);
}
}
then:
[Serializable]
internal class ExistensHU : IDialog<object>
{
private Renamer renamer = new Renamer(); // Just for renaming
private ExternalConnection ec = new ExternalConnection(); //Just a HTTP connection to a WebApp to get data from it
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
const string apiCallURL = "some/API/"; // ExternalConnection...
var message = await result;
string nameHU = renamer.RemoveBlanks(message.Value.ToString());
StringBuilder answerBuilder = new StringBuilder();
var name = ec.CreateSingleAPIParameter("name", nameHU);
Dictionary<string, string> wms = await ec.APIResultAsDictionary(apiCallURL, name);
foreach (var item in wms)
{
if (item.Key.Equals("none") && item.Value.Equals("none"))
{
answerBuilder.AppendLine($"Wrong Answer");
}
else
{
answerBuilder.AppendLine($"Correct Answer");
}
}
await context.PostAsync(answerBuilder.ToString());
context.Done<object>(null);
}
}
That's basically every Dialog in my project.
Also I have an IDialog which looks like this:
[Serializable]
public class VerificationDialog : IDialog<object>
{
[NonSerializedAttribute]
private readonly LuisResult _luisResult;
public VerificationDialog(LuisResult luisResult)
{
_luisResult = luisResult;
}
public async Task StartAsync(IDialogContext context)
{
var message = _luisResult.Query;
if (!message.StartsWith("Wie viele"))
{
context.Call(new ByVerificationDialog(_luisResult), AfterDialog);
}
else
{
context.Call(new CountBinsByVerification(_luisResult), AfterDialog);
}
}
private async Task AfterDialog(IDialogContext context, IAwaitable<object> result)
{
context.Done<object>(null);
}
}
I don't know if I'm allowed to pass the luisResult like this from BasicLuisDialog. This could be the issue or one of the issues.
Basically that's it and I'm still getting used to the framework. I'm not expecting an absolute answer. Just hints/tips and advice how to make everything better.
Thanks in advance!
If you are using the .NET SDK version 3.14.0.7. There is currently a bug we are tracking in this version. There has been a number of reports and we are actively investigating. Please try downgrading to 3.13.1. This should fix the issue for you until we can release a new version.
for reference we are tracking the issue on these GitHub issues:
https://github.com/Microsoft/BotBuilder/issues/4322
https://github.com/Microsoft/BotBuilder/issues/4321
Update 3/21/2018:
We have pushed a new version of the SDK which includes a fix for this issue https://www.nuget.org/packages/Microsoft.Bot.Builder/3.14.1.1
Internal error usually means exceptions in .NET application.
Use AppDomain.CurrentDomain.UnhandledException to receive all unhandled exceptions and log them somewhere (consider using Application Insights).
After you investigate logged information fix that.
I'm struggling to find out where my MessageWebSocket.OutputStream disposes.
WebsocketManager():
public WebsocketManager()
{
baseInit();
}
baseInit():
private void baseInit()
{
messageWebsocket = new MessageWebSocket();
}
connect():
public async void connect(string token, IEventAggregator eventAggregator, EvaLogger evaLogger)
{
try
{
messageWebsocket.SetRequestHeader("iPlanetDirectoryPro", token);
_eventAggregator = eventAggregator;
_evaLogger = evaLogger;
_localDataManager = new SqliteLocalDataManager(_evaLogger, _eventAggregator);
messageWebsocket.MessageReceived += OnMessageReceived;
messageWebsocket.Closed += OnClosed;
messageWebsocket.Control.MessageType = SocketMessageType.Utf8;
await messageWebsocket.ConnectAsync(WSURI);
}
catch (Exception e)
{
_evaLogger.Error(e.Message, e);
}
}
requestChats():
public async void requestChats()
{
DataWriter dataWriter = new DataWriter(messageWebsocket.OutputStream);
dataWriter.WriteString(WebsocketRequestFactory.Create(SocketEventsEnm.GET_CHATS));
await SendData(dataWriter);
}
sendTextMessage():
public async void sendTextMessage(long chatId, string message)
{
DataWriter dataWriter = new DataWriter(messageWebsocket.OutputStream);
dataWriter.WriteString(WebsocketRequestFactory.Create(SocketEventsEnm.MESSAGE_OUT, chatId, message));
await SendData(dataWriter);
}
SendData():
private async Task SendData(DataWriter dataWriter)
{
try
{
_evaLogger.Info("Trying to send data...");
await dataWriter.StoreAsync();
_evaLogger.Info("Data was sent");
}
catch (Exception e)
{
_evaLogger.Error(e.Message, e);
}
}
Everything is working as intended, I can call requestChats() without a problem, but when I call sendTextMessage(), I get an System.ObjectDisposedException. I could also call requestChats() instead of sendTextMessage(). But after I call one of these methods a second time, I will get System.ObjectDisposedException.
I am pretty sure that it's the MessageWebSocket.OutputStream which is disposed, but I don't know where it's getting disposed. But maybe it's a thing about threads and not about disposing?
If you need any additional information, just ask. I keep struggling for the whole day with this issue.
EDIT 1:
Still couldn't figure out the problem. Today I tried the following things:
Change MessageWebSocket to ClientWebSocket: Other exception but it means the same:
The WebSocket is in an invalid state ('Closed')
Use a session variable for the WebSocket. It didn't solve the problem either
I am grateful for every idea, even if it's just a very small one...
I was able to fix the problem. Before I send data, I was always creating a new DataWriter. Now I only create one DataWriter which gets initializied when I connect the WebSocket to the server.
I guess the problem was that when the datawriter got cleaned by the garbage collector, the outputstream got closed. Imo the datawriter shouldn't have that much power, but that's my only explanation.
So I have a service set up to import a large amount of data from a file the user uploads. I want to the user to be able to continue working on the site while the file is being processed. I accomplished this by creating a thread.
Thread.start {
//work done here
}
Now the problem arises that I do not want to have multiple threads running simultaneously. Here is what I tried:
class SomeService {
Thread thread = new Thread()
def serviceMethod() {
if (!thread?.isAlive()) {
thread.start {
//Do work here
}
}
}
}
However, this doesn't work. thread.isAlive() always return false. Any ideas on how I can accomplish this?
I would consider using an Executor instead.
import java.util.concurrent.*
import javax.annotation.*
class SomeService {
ExecutorService executor = Executors.newSingleThreadExecutor()
def serviceMethod() {
executor.execute {
//Do work here
}
}
#PreDestroy
void shutdown() {
executor.shutdownNow()
}
}
Using a newSingleThreadExecutor will ensure that tasks execute one after the other. If there's a background task already running then the next task will be queued up and will start when the running task has finished (serviceMethod itself will still return immediately).
You may wish to consider the executor plugin if your "do work here" involves GORM database access, as that plugin will set up the appropriate persistence context (e.g. Hibernate session) for your background tasks.
Another way to do this is to use Spring's #Async annotation.
Add the following to resources.groovy:
beans = {
xmlns task:"http://www.springframework.org/schema/task"
task.'annotation-driven'('proxy-target-class':true, 'mode':'proxy')
}
Any service method you now annotate with #Async will run asynchronously, e.g.
#Async
def reallyLongRunningProcess() {
//do some stuff that takes ages
}
If you only want one thread to run the import at a time, you could do something like this -
class MyService {
boolean longProcessRunning = false
#Async
def reallyLongRunningProcess() {
if (longProcessRunning) return
try {
longProcessRunning = true
//do some stuff that takes ages
} finally {
longProcessRunning = false
}
}
}
Silverlight can only send a certain number of simultaneous WCF requests at a time. I am trying to serialize the requests that a particular section of my application is performing because I don't need them to run concurrently.
The problem is as follows (summary below):
"WCF proxies in Silverlight applications use the SynchronizationContext of the thread from which the web service call is initiated to schedule the invocation of the async event handler when the response is received. When the web service call is initiated from the UI thread of a Silverlight application, the async event handler code will also execute on the UI thread."
http://tomasz.janczuk.org/2009/08/improving-performance-of-concurrent-wcf.html
summary: basically, if you block the thread that is calling the async method, it will never get called.
I can't figure out the right model of threading this such which would give me what I want in a reasonable way.
My only other requirement is that I don't want the UI thread to block.
As far as I can see, what should work is if the UI thread has a worker thread which queues up the calls as Action delegates, then uses an AutoResetEvent to execute a task one at a time in yet another worker thread. There are two problems:
1) The thread that calls async can't block, because then async will never get called. In fact, if you put that thread into a wait loop, I've noticed it doesn't get called either
2) You need a way to signal from the completed method of the async call that it is done.
Sorry that was so long, thanks for reading. Any ideas?
I have used a class that i build on my own to execute load operations synchronous. With the class you can register multiple load operations of diffrent domaincontexts and then execute them one by one. You can provide an Action to the constructor of the class that gets called, when all operations are finished (successful or failed).
Here´s the code of the class. I think it´s not complete and you have to change it to match your expectations. Maybe it can help you in your situation.
public class DomainContextQueryLoader {
private List<LoadOperation> _failedOperations;
private Action<DomainContextQueryLoader> _completeAction;
private List<QueuedQuery> _pendingQueries = new List<QueuedQuery>();
public DomainContextQueryLoader(Action<DomainContextQueryLoader> completeAction) {
if (completeAction == null) {
throw new ArgumentNullException("completeAction", "completeAction is null.");
}
this._completeAction = completeAction;
}
/// <summary>
/// Expose the count of failed operations
/// </summary>
public int FailedOperationCount {
get {
if (_failedOperations == null) {
return 0;
}
return _failedOperations.Count;
}
}
/// <summary>
/// Expose an enumerator for all of the failed operations
/// </summary>
public IList<LoadOperation> FailedOperations {
get {
if (_failedOperations == null) {
_failedOperations = new List<LoadOperation>();
}
return _failedOperations;
}
}
public IEnumerable<QueuedQuery> QueuedQueries {
get {
return _pendingQueries;
}
}
public bool IsExecuting {
get;
private set;
}
public void EnqueueQuery<T>(DomainContext context, EntityQuery<T> query) where T : Entity {
if (IsExecuting) {
throw new InvalidOperationException("Query cannot be queued, cause execution of queries is in progress");
}
var loadBatch = new QueuedQuery() {
Callback = null,
Context = context,
Query = query,
LoadOption = LoadBehavior.KeepCurrent,
UserState = null
};
_pendingQueries.Add(loadBatch);
}
public void ExecuteQueries() {
if (IsExecuting) {
throw new InvalidOperationException("Executing of queries is in progress");
}
if (_pendingQueries.Count == 0) {
throw new InvalidOperationException("No queries are queued to execute");
}
IsExecuting = true;
var query = DequeueQuery();
ExecuteQuery(query);
}
private void ExecuteQuery(QueuedQuery query) {
System.Diagnostics.Debug.WriteLine("Load data {0}", query.Query.EntityType);
var loadOperation = query.Load();
loadOperation.Completed += new EventHandler(OnOperationCompleted);
}
private QueuedQuery DequeueQuery() {
var query = _pendingQueries[0];
_pendingQueries.RemoveAt(0);
return query;
}
private void OnOperationCompleted(object sender, EventArgs e) {
LoadOperation loadOperation = sender as LoadOperation;
loadOperation.Completed -= new EventHandler(OnOperationCompleted);
if (loadOperation.HasError) {
FailedOperations.Add(loadOperation);
}
if (_pendingQueries.Count > 0) {
var query = DequeueQuery();
ExecuteQuery(query);
}
else {
IsExecuting = false;
System.Diagnostics.Debug.WriteLine("All data loaded");
if (_completeAction != null) {
_completeAction(this);
_completeAction = null;
}
}
}
}
Update:
I´ve just noticed that you are not using WCF RIA Services, so maybe this class will not help your.
There are some options:
- You can take a look at the Agatha-rrsl either by inspecting the implementation of it or by just using it instead of pure wcf. The framework allows you to queue requests. You can read more here.
- Another option is to use the Reactive extension. There is a SO example here and more info here and here.
- You can try the Power Thread library from Jeffrey Richter. He describes it on his book CLR via C#. You can find the library here. This webcast gives you some info about it.
- You can always roll your own implementation. The yield statement is a good help here. Error handling makes it very difficult to get the solution right.