Is there any way to stop a script after it has executed a particular amount of time?
This is a rather vaguely defined question. Here are a few ideas that come to mind:
Use a shell as the control process. Start the JRuby script, send it into the background, sleep for a fixed amount of time, then kill $!.
At the beginning of your JRuby script, create a thread that sleeps for a fixed amount of time, and then kill the entire script.
If you're using an embedded JRuby, you can use Java's threads to do exactly what you want.
I have the same question. My current approach looks like this (and does not work as expected...):
// jruby-complete-1.6.0.RC2.jar
import org.jruby.Ruby;
class JRubyStop {
public static void main(String[] args) throws InterruptedException {
final Ruby jruby = Ruby.newInstance();
Thread jrubyThread = new Thread() {
public void run() {
String scriptlet = "for i in 0..100; puts i; sleep(1); end";
jruby.evalScriptlet(scriptlet);
}
};
jrubyThread.start();
Thread.sleep(5000);
System.out.println("interrupt!");
jrubyThread.interrupt();
System.out.println("interrupted?!");
}
}
After the output of "interrupted?!" the thread still runs until the scriptlet ends.
Edit: Converted Groovy example into a Java SSCCE (http://sscce.org/).
super late answer but this is what I use:
require 'timeout'
status = Timeout::timeout(5)
{
# Something that should be interrupted if it takes more than 5 seconds...
}
Related
Here is my Desktop Launcher code:
public class DesktopLauncher {
public static void main (String[] arg) {
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setForegroundFPS(60);
config.setTitle("Game10");
config.setWindowedMode(1240, 760);
config.forceExit = false; // ERROR!!!
new Lwjgl3Application(new GdxGame10(), config);
}
}
In new LWJGL3 config.forceExit not working. I can't find any solution so far. Any help is appreciated.
There is no forceExit in config. So presumably you have a master application that runs a child libGDX component and when you end that child component you find that the entire application shuts down, when you want the master application to continue. I guess you are on desktop because Android would be OK. So you must want to avoid a full System.exit
i.e.
Gdx.app.exit()
shuts down everything.
So when you instantiate a libGDX application you instantiate based on the application type, so for me, I use the same as you
final Lwjgl3Application application = new Lwjgl3Application(Services.GAME_CONTROLLER,config);
and the implementation for exit is
#Override
public void exit () {
running = false;
}
This finished the while loop that drives the application i.e. kills the main thread. If you have -other threads- running in the background they keep going.
If on the other hand you were instantiating LwglAWTCanvas then your shutdown would be this.
#Override
public void exit () {
postRunnable(new Runnable() {
#Override
public void run () {
stop();
System.exit(-1);
}
});
}
which would shut down the entire application. Anyway so forceExit being -false- was to stop a full system exit killing all your threads. The forceExit was to "force" the other threads to finish. It doesn't do that anymore so the fact it is now missing should not matter, your background threads should keep going.
In other words, config.forceExit = false; is now the default behaviour for your application type so you don't need it.
Because of I had problems with Bluetooth on Android Lollipop, I have tried to change the scanner method.
So I have tried to use the new package.
In the previous version, I called startScan(mLeScanCallback) and everything works but now, when I call startScan(mScanCallback) I have the error: "D/BluetoothLeScanner: could not find callback wrapper".
No devices are found and the ListAdapter, I use to show the devices, is empty.
The comment lines are the previous code (and it worked!).
This my code:
public class Selection extends ListActivity implements ServiceConnection {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
// Initializes a Bluetooth adapter through BluetoothManager.
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
getApplicationContext().bindService(new Intent(this, MetaWearBleService.class), this, Context.BIND_AUTO_CREATE);
}
private void scanLeDevice(final boolean enable) {
final BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if (enable) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
//mBluetoothAdapter.stopLeScan(mLeScanCallback);
bluetoothLeScanner.stopScan(mScanCallback);
setListAdapter(listAdapter);
}
}, SCAN_PERIOD);
//mBluetoothAdapter.startLeScan(mLeScanCallback);
bluetoothLeScanner.startScan(mScanCallback);
} else {
//mBluetoothAdapter.stopLeScan(mLeScanCallback);
bluetoothLeScanner.stopScan(mScanCallback);
setListAdapter(listAdapter);
}
}
private ScanCallback mScanCallback =
new ScanCallback() {
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
listAdapter.addDevice(device);
}
});
}
};
Instead the ListAdapter extends BaseAdapter and use a ViewHolder. If it necessary, I post it.
So what does it mean "D/BluetoothLeScanner: could not find callback wrapper"? What is it wrong?
Otherwise how I can't resolve the problem of scanning with the Android Lollipop?
In Lollipop I have often errors about BluetoothGatt. I don't know to minized it (or solve it).
Thanks
The log message D/BluetoothLeScanner: could not find callback wrapper appears whenever Android's bluetooth scanning APIs are told top stop scanning for an app when they think scanning has not started. You can see this by looking at the source code of Android's BluetoothLeScanner here.
This is usually safe to ignore as there are lot of reasons that scanning my not have actually started (it was already stopped, bluetooth is off, permissions have not been granted, etc.) Client software that does scanning often stops scanning on a timer regardless of whether it has been successfully started, or whether it was manually stopped before the timer goes off. Android's example code (and the code shown above) does exactly this, often causing these log messages to show up.
If you really want to minimize these messages, you need to keep track of whether scanning actually started and only stop scanning if it actually did. Unfortunately, you don't get a return code if scanning starts successfully, and you only get an asynchronous callback to onScanFailed(errorCode) if you cannot start successfully. So one approach would be to set scanStartCount++; when you call start scan, and set scanStartCount--; when you get a callback to onScanFailed(errorCode). Then when your timer goes off to stop the scan, only actually stop it if the scanStartCount > 0.
Keep in mind that you can only minimize these messages coming from your application. Other applications on the phone doing bluetooth scanning may be causing these messages to be emitted as well.
for the same problem
I had just add permissions :
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.
Manifest.permission.
Manifest.permission.BLUETOOTH_PRIVILEGED,
in your activity call this methods :
checkPermissions(MainActivity.this, this);
public static void checkPermissions(Activity activity, Context context){
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_PRIVILEGED,
};
if(!hasPermissions(context, PERMISSIONS)){
ActivityCompat.requestPermissions( activity, PERMISSIONS, PERMISSION_ALL);
}
}
public static boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
hope it's help
I had the same problem with android m.It was due to lack of permissions.Make sure you go to settings and grant location permission to your app
for location permission, only ACCESS_FINE_LOCATION worked. ACCESS_COARSE_LOCATION had the same problem.
In a project at work I came across a real annoying bug/feature. I found a sollution however I'm really curious to the why it is happening. It all has to do that the project has some legacy tests written with unitils instead of plain old EasyMock. Consider following two test classes ran in order right behind eachother.
public class Test1{
#TestedObject
private MyService myService;
#InjectIntoByType protected Mock<MyRepository> myRepo;
#Test
public void aTest(){
myService.doSomething();
myRepo.assertNotInvoked().getById(EasyMock.anyLong());
}
}
public class Test2{
private IMocksControl control;
private MyOtherService myService;
private MyOtherRepo myRepo;
public Test2(){
control = EasyMock.createControl();
myRepo = control.createMock(MyOtherRepo.class);
myService = new MyOtherService(myRepo);
}
#Test
public void aTest(){
myRepo.getById(5L);
EasyMock.expectLastCall().andReturn(new MyObject(5L));
control.replay()
MyObject result = myService.doSomething();
control.verify()
Assert.assertEquals(5L,result.getId().longValue);
}
}
When I run both test seperatly they run fine. Both green both working. However if I run them right after eachother the second test fails with
java.lang.IllegalStateException: x matchers expected, y recorded error (x and y are ints ofcourse, just since this is a fake example I don't have real numbers).
I "fixed" this by changing the assertNotInvoked line to : myRepo.assertNotInvoked().getById(null);
This is ofcourse not really a fix, I just circumvented the use of matchers and I'm wondering if I just didn't break the legacy test case with it ... Is there anyone with enough EasyMock + Unitils experience that could help me understand this ? My best "guess" is that AssertNotInvoked isn't properly ended with a EasyMock.replay(), EasyMock.verify() block ... but I could be wrong.
I have tried to locate the solutions to my problem in various message boards. However, I am running into walls. I am trying to recreate a problem that is happening on our database "LockWait Timeout" on a Mysql INNODB table. (for information about my issue I am trying to solve, go to: http://bugs.mysql.com/bug.php?id=10641 )I have narrowed down the issue, and I have a solution. But I cannot recreate the issue on a test environment so I can test my solution.
Here is my code:
public static void main(String[] args) {
System.out.println("Programm Starting");
int numberOfthreads = 2;
for(int x = 1; x <= numberOfthreads; x++){
//Create the object UpdateClass
// Create the Runable object
Runnable r = new Runnable() {
// Start the Runnable
public void run() {
System.out.println("Running");
}
};
Thread thr = new Thread(r);
System.out.println("Thread object created");
thr.start();
final UpdateClass session = new UpdateClass(x);
System.out.println("Thread object started");
try {
System.out.println("Starting UpdateClass.runProcess()");
session.runProcess();
Thread.sleep(1);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
thr.stop();
System.out.println("Thread stopped");
}
}
Basically, I am trying to replicate simultaneous UPDATEs to the MySql table to create the LockWait Timeout issue.
My class UpdateClass works the way I need it to, but I cannot recreate the simultaneous events to call the class.
Question: How can I alter my code to increase the probability of generating the conditions that lead to the timeout?
few things you could try to replicate the issue in test:
change the innodb_lock_wait_timeout in the mysqlcnf to a small time interval or increase the thread sleep time (if you change the cnf file, you will need to restart the DB server)
Ensure that you are holding onto a lock (and have not released it) before the thread goes to sleep (you could possibly achieve the same with a network disconnect/DB connection going down while the lock has not been released but not entirely certain about that).
I am assuming that your MySQL version is the same as in production.
my question is simple, yet I couldn't find any answer of it in the net, maybe it's impossible to do...
The thing is that I have an ActionScript 3.0 application, and wanted to include a little one-line size textbox which showed all the trace() calls and such, which are shown in the console.
Has anyone got any idea of how can it be done? I would really appreciate it, as I have a full project with traces on it that I'd like to show, and it's now when I'm finishing that I'm realising I don't know how to do it :P
Of course not everything is lost, as I could just do my own class that showed there the messages, but it would be cleanier, and quicker not to have to replace all the trace() calls for my new class and method.
Regards and thanks in advance :)
I just did this last week.
There are logging frameworks for Flex out there. A shame, though, that Flex's logging only works in Debug mode. If you search SO for Flex logging you'll find various suggestions. None of them are amazing, IMO.
Finally I rolled my own by just creating a Log class with a static function that acts as a proxy for trace.
Something like:
public static myTrace(... args) : void { ... }
Then you just forward the args to trace but also to whatever other destination you want (e.g. an array of strings + dates) that you can then display in the log window.
Incidentally, I also used SwfAddress to trigger the log window whenever a certain parameter is added to the URL. Very handy.
Oh, what the heck.. here's the class. It just keeps the last 100 strings and there's also a "dump" function that you can invoke if you want to send the data to your server or just quickly print the entire history.
public class Log
{
public static var lines : ArrayList = new ArrayList();
public static const MAX_LINES : int = 100;
private static function logLine(line : String) : void
{
while (lines.length > MAX_LINES)
lines.removeItemAt(0);
lines.addItem({"line" : line, "time" : new Date()});
}
public static function logDump() : String
{
var ret : String = "";
for each (var entry : Object in lines.source)
{
ret = (entry.time as Date).toUTCString() + " " + entry.line + "\n" + ret;
}
return ret;
}
public static function debug(...args) : void
{
trace(args);
var line : String = "";
for (var i : int = 0; i < args.length; i++)
if (args[i] != null)
line += args[i].toString();
logLine(line);
}
}
Alternatively, you can use the ASDebugger
http://labs.flexperiments.nl/asdebugger-20-a-real-time-debugger-and-editor/
ASDebugger.debug( 'shallala' );
ASDebugger.debug_prop( variable );
Try to avoid using the debug display object option. The debugger can crash for complex objects (especially in flex)
You can probably do a simple replacement of 'trace(' to 'ASDebugger.debug('