setTimeOut and local function - x++

I'm working on Ax 4.0
I'm trying to use the Object.setTimeOut method in a job with a local function, as stated in the msdn documentation :
static void setTimeOutJob()
{
Object o = new Object();
void printText()
{
;
info( "2 seconds has elapsed since the user did anything" );
}
;
// Set a Time Out with the idle flag set to false
o.setTimeOut(identifierstr(printText), 2000, false);
}
But this simple job doesn't produce anything, so it seems I'm missing something here.
Has someone worked with this ?

The setTimeout method does not work with a local function in a job.
For a working example have a look on the form tutorial_Timer instead.
Update:
The setTimeout method is a "magic" function, but it does not turn AX into a multithreading environment.
It only works while a Windows event loop is in action. In the AX context it means that a form is running and someone else is waiting for the form to complete. The sleep function does not meet the criteria.
Also the object must be "alive", calling a garbage collected object is no good!
Example (class based):
class SetTimeoutTest extends Object //Yes, extend or it will not compile
{
str test;
}
public void new()
{
super();
test = "Hello";
}
public str test()
{
return test;
}
protected void timedOut()
{;
test = "2 seconds has elapsed since the user did anything";
info(test);
}
static void main(Args args)
{
SetTimeoutTest t = new SetTimeoutTest();
FormRun fr;
;
t.setTimeOut(methodStr(SetTimeoutTest,timedOut), 2000, false);
//sleep(4000); //Does not work
fr = ClassFactory::formRunClassOnClient(new Args(formstr(CustGroup))); //Could be any form
fr.init();
fr.run();
fr.wait(); //Otherwise the t object runs out of scope
info(t.test());
}

I just don't think it works with jobs. I've used it on forms where the method is on the element level, and have done element.setTimeout and it works fine.

Related

how to wait for the completion of Future without 'async'

how to wait for the completion of Future without 'async' and 'futures'?
In the library that I use all functions are asynchronous.
// must return <bool>
bool my_func(int x){
//returns Future<int>
var tmp = somelib.somefunc( ... );
//wait y
return x == y;
}
I tried to write my 'await', but
waiting for a result with a while loop freezes everything.
dynamic my_await(Future f) {
dynamic x;
bool completed = false;
f.then((v){
x = v;
completed = true;
});
do {} while (!completed);
return x;
}
Dart VM version: 1.24.3 (Mon Dec 18 16:57:48 2017) on "linux_x64"
A synchronous function, or really, any Dart function, returns a value immediately when you call them. If you want to return a boolean immediately, and the value of that boolean depends on the result that some future completes with, then there is no way to compute that boolean in time.
If you need to wait for a future, then your function is asynchronous. You need to return something immediately, even if you don't know the result yet. That's what a Future is. It's not magical in any way, it's just an object that you can set a callback on which gets called when some result is ready.
So, you need to return a Future<bool> for this to work.
Dart is single-threaded. Without using isolates, there is no concurrency. Instead asynchronous functions work by taking turns, giving time for other code to run, e.g., while they wait on a future. If you just do a do {} while (!completed); then no other code gets to run, which means that nothing will be able to set completed to true.
I'm new to dart, so not sure if this is the correct way of doing it, but I've solved this issue by using the function whenCompleted() on the Future returned by the async method I'm calling.
Here openDatabase returns a Future.
abstract class IBaseDatabaseHandler {
Database sqliteDbHandler;
IBaseDatabaseHandler.sqlite(String dataBasePath) {
sqfliteFfiInit();
var databaseFactory = databaseFactoryFfi;
databaseFactory
.openDatabase(dataBasePath)
.whenComplete(() => sqliteDbHandler);
}
}

GLib: g_source_remove() not stopping timeout callbacks on non-default GMainContext

I am using this function to add a timeout callback (repeated) to a specific GMainContext.
guint GstThreadHelper::timeoutAdd(guint delay, GSourceFunc function, gpointer data) {
// See https://developer.gnome.org/programming-guidelines/stable/main-contexts.html.en#implicit-use-of-the-global-default-main-context
// It is important that all thread functions we invoke don't implicitly decide a maincontext.
// We must manually provide one.
GSource *source = NULL;
guint id;
source = g_timeout_source_new(delay);
g_source_set_callback (source, function, data, NULL);
id = g_source_attach (source, priv->mainContext);
g_source_unref (source);
return id;
}
Later, I use the returned id to cancel the callback.
void GstThreadHelper::timeoutRemove(guint id) {
g_source_remove(id);
}
However, the callback still gets called. Here is my callback.
static gboolean position_update (gpointer user_data)
{
Player::PrivateData* priv = (Player::PrivateData*)user_data;
gint64 pos = 0;
if (gst_element_query_position (priv->playbin, GST_FORMAT_TIME, &pos)) {
pos = pos / 1000000;
priv->callback->PositionChanged(pos);
}
// Call me again
return TRUE;
}
I understand I am returning TRUE, but my understanding is that it still should be stopped. If I cancel callbacks by returning FALSE, I wouldn't bother with the g_source_remove call.
Why doesn't g_source_remove stop my callback from being raised?
EDIT
If I replace my timeoutAdd method with this...
guint GstThreadHelper::timeoutAdd(guint delay, GSourceFunc function, gpointer data) {
return g_timeout_add(delay, function, data);
}
...it works. However, I can't use this, because it doesn't trigger the callbacks on a specific GMainContext, as opposed to the default global GMainContext.
EDIT2
I copied the default source for g_timeout_add_seconds_full into my function, and it worked.
However, the moment I changed g_source_attach to use my private GMainContext, it failed.
The issue is something to do with calling g_source_remove for timeouts added on non-default GMainContexts.
It turns out that g_source_remove operates under the assumption that you are using the global/default GMainContext, which in this case, I am not.
I don't remember reading this in the docs.
Anyways, Here is the solution.
void GstThreadHelper::timeoutRemove(guint id) {
GSource* source = g_main_context_find_source_by_id(priv->mainContext, id);
if (source)
g_source_destroy (source);
}
This is essentially what g_source_remove is doing, but instead using our private GMainContext.

Websocket Server Issue: onOpen hit client side, but server websocket handler OnOpen and other events never hit

I am very new to websockets and WebAPI (our system has been all .NET MVC, just not WebAPI), so I may very well just be missing something obvious (I hope).
I am attempting to implement a simple client to play around with. I am working in .NET in (sadly) VB, and I'm trying to just get the websocket working, and hitting the OnOpen/Message/Close events server and client side.
My code is below, but in short, the websocket handshake seems to happen without any issue, as my onOpen() event in the javascript gets hit, and when I output the readyState its 1. However OnOpen does NOT get hit server side
The output ends up looking like this:
IMMEDIATE READYSTATE: 0
ONOPEN READYSTATE: 1
Socket closed
The constructor for my WebSocketHandler is hit (for example if I throw a breakpoint on the MyBase.New() line, it hits it). However OnOpen is never hit, and the socket immediately hits the onclose event in the js.. is there something I should be doing to keep the socket open? Why would OnOpen not get hit?
My code is below:
Javascript:
var wsUri = 'ws://' + window.location.hostname + '/api/Chat?username=hello';
var output;
$(document).ready(function () {
//setup and fire
output = document.getElementById("output");
testWebSocket();
})
function testWebSocket() {
//Instantiate the websocket, hopefully opening it
websocket = new WebSocket(wsUri);
writeToScreen("IMMEDIATE READYSTATE: " + websocket.readyState);
//bind event handlers
websocket.onopen = function (evt) { onOpen(evt) };
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
}
function onOpen(evt) {
writeToScreen("ONOPEN READYSTATE: " + websocket.readyState);
websocket.send("Websocket's open!")
}
function onClose(evt) {
writeToScreen("Socket closed");
}
function onMessage(evt) {
writeToScreen('RECEIVED: ' + evt.data);
}
function onError(evt) {
writeToScreen('ERROR:' + evt.data);
}
function writeToScreen(message) {
var messageToAppend = document.createElement("p");
messageToAppend.style.wordWrap = "break-word";
messageToAppend.innerHTML = '<span>' + message + '</span>';
output.appendChild(messageToAppend);
}
Server:
Public Class ChatController
Inherits ApiController
Public Function [Get](username As String) As HttpResponseMessage
If HttpContext.Current.IsWebSocketRequest Then
HttpContext.Current.AcceptWebSocketRequest(Function() Tasks.Task.FromResult(New ChatWebSocketHandler(username)))
Return Request.CreateResponse(HttpStatusCode.SwitchingProtocols)
Else
Return Request.CreateResponse(HttpStatusCode.BadRequest)
End If
End Function
Private Class ChatWebSocketHandler
Inherits Microsoft.Web.WebSockets.WebSocketHandler
Public Sub New(username As String)
MyBase.New()
'Do stuff with username eventually.
End Sub
Public Overrides Sub OnOpen()
Debug.WriteLine("Websocket is open")
End Sub
Public Overrides Sub OnMessage(message As String)
Debug.WriteLine("Message Received: " & message)
End Sub
Public Overrides Sub OnClose()
Debug.WriteLine("Websocket Closed")
MyBase.OnClose()
End Sub
End Class
End Class
To be honest, I cant say with 100% certainty what fixed this, but I have a very strong suspicion.
I was including too many namespaces in my code and I believe there was some confusion in the compiler etc when it actually ran. Apparently both Microsoft.Web.Websockets and SignalR's namespaces BOTH contain WebSocketHandler. While I dont know all the ins and outs of SignalR, it looks like WebSocketHandler in THAT namespace is not meant to be used outside of SignalR. I believe that class was being referenced instead of the one in Microsoft.Web.Websockets, as it works now, but I really didn't change too much. It also let me directly call the constructor by instantiating a new instance of the handler instead of having to call it in a lambda function.
Anyway, If anyone else has similar issues, make sure you're referencing the right one!

Scheduling the same activity with different arguments in Amazon SWF

I am trying to schedule an activity in Amazon SWF. Initially, I used to loop through a list and schedule the activity for each value of the list. But this would invoke the activities in parallel which I did not want. So, I modified my code to do something like this:
Promise<Void> promiseArg = null;
for(Integer i : IntegerList){
Promise<Void> nextArg = activityClient.activity1(i);
promiseArg = nextArg;
}
Though code is working, I am not sure if this is the right way to do it. Any comments would be helpful.
What is the point of using promiseArg if it is unused?
If you want them to be dependent on prev method call, create an Asynchronous method and call that with promise variable.
//Main method of decider.
Promise<Integer> promiseArg = null;
Promise<Integer> nextArg = activityClient.activity1(i, 1);
for(Integer i : IntegerList){
Promise<Integer> nextArg = fun(nextArg, Promise.asPromise(i));
}
#Asynchronous
public Promise<Integer> fun(Promise<int> nextArg, int i) {
System.out.println("Testing with current value: " + Integer.toString(nextArg.get()));
return activityClient.activity1(i, nextArg.get());
}
I haven't tested it but it should work.
Apart from this, you can also try passing prev Promise variable to activity itself with #Wait annotation in the activity declaration.
Something like this,
prevArgs = activityClient.activity1(i, prevArg));
with Activity like,
XYZ activity1(int i,#Wait Promise<int> prevArgs){
//Please check if int should be used instead of Promise<int>
}

Windows Service always "Starting" because of infinite loop in OnStart() method

I've written a Windows Service that periodically executes a SSIS package that moves documents from Server A to Server B.
The problem is that in order to do so, I need to use an infinite loop, which starts when the Service starts.
Naturally, I placed this loop into the OnStart() method. Unfortunately, the service never signals that it has started, since it never reaches the end of this method...
Here is the relevant code:
protected override void OnStart(string[] args)
{
Application app = new Application();
Package pkg = app.LoadFromDtsServer(#"MSDB\PullDoc", "Server", null);
while (true)
{
DTSExecResult pkgResults = pkg.Execute();//Execute the package.
EventLog.WriteEntry(pkgResults.ToString());
Thread.Sleep(1000 * 60 * 5);//Sleep at least five minutes.
}
}
I would imagine this is a common problem, given that most Services should be running indefinitely.
Any ideas on how to get this service to return that it has started?
Thanks!
You should use a System.Threading.Timer instead of an infinite loop.
Your service should do its work on a different thread. The OnStart, OnStop etc methods are there to process commands to your service from the Windows Service Control Manager (SCM), and the SCM expects them to return promptly.
Using a System.Threading.Timer as suggested by #SLaks achieves this: the timer events will be executed on a thread from the .NET Thread Pool. Your OnStart method just Enables the Timer, while the OnStop method disables it (OnPause and OnResume can do likewise if you want).
You are not doing this correctly, you should never block a function from returning and you should use a new Thread. As it was suggested, you should use a Timer object.
Here is a code snippet to show you how:
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
CopyAToB();
}
Timer timer = new Timer();
protected override void OnStart(string[] args)
{
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 60000 * 5;
timer.Enabled = true;
}
private void CopyAToB()
{
// do somethings
}
I would recommend that you use a System.Threading.Timer like suggested but here is an example of how I would implement the functionality.
In this example I have the function fire 4 times an hour and it will quickly validate if its still running from the previous call and if so skip it otherwise it will create a new thread and fire off the function.
Imports System.Threading
Public Class myService
Private myThreadingTimer As System.Threading.Timer
Private keepRunning As Boolean = False
Private processing As Boolean = False
Protected Overrides Sub OnStart(ByVal args() As String)
Dim myTimerCallback As New TimerCallback(AddressOf OnTimedEvent)
If YourCheckHere() Then
keepRunning = True
myThreadingTimer = New System.Threading.Timer(myTimerCallback, Nothing, 1000, 1000)
Else
'What you want to do here
End If
End Sub
Protected Overrides Sub OnStop()
keepRunning = False
End Sub
Private Sub OnTimedEvent(ByVal state As Object)
If Date.Now.Minute = 14 And Date.Now.Second = 31 Or Date.Now.Minute = 29 And Date.Now.Second = 31 _
Or Date.Now.Minute = 44 And Date.Now.Second = 31 Or Date.Now.Minute = 59 And Date.Now.Second = 31 _
Then
'Make Sure Its Supposed To Still Be Running
If keepRunning Then
'Make Sure The Process Is Not Already Running
If Not processing Then
'Process is not currently running lets start it
Dim myThread As New Thread(New ThreadStart(AddressOf myProcess))
myThread.Start()
End If
End If
End If
End Sub
Public Sub myProcess()
Try
' Set the processing flag so the function does not run again until complete
processing = True
'Do whatever logic you need here
Catch ex As Exception
'Since You Can Not Use A MessageBox Do Logging Or Whatever You Need Here
Finally
processing = False
End Try
End Sub
End Class

Resources