The Problem

If you use VNC to remotely connect to your machines and are having problems with certain applications not showing changes (redrawing), this will, hopefully, solve the problem for you.

The symptoms are simple: you load a program but only the program outline and maybe the first frame would show up. After that, nothing would update, even though the user in front of the remote computer can see everything updating fine. For me, it is happening with all Java based programs (SmartSVN, Charles - amazing program btw!, etc). Here's what's happening to my Charles application - it never even sent the first frame, simply showing the desktop and not updating:

image

The problem may be confined to RealVNC only, or at least any VNC program that uses a special mirror driver. You can tell whether your VNC server uses a mirror driver by looking at your Settings->Desktop options under "Optimise screen capture (mirror driver)":

image

The Solution

I'm not sure if it's Java's fault or the mirror driver's but, as it turns out, the mirror driver does not properly work with Java based programs, at least at the moment. Disabling it, or switching to application hooking fixes the problem. There is most likely a benefit in using a mirror driver as it is probably optimized better than other methods, but it's not worth keeping if you are having problems with it.

The easiest way to disable the setting is to uncheck the checkbox above. You can also alternatively go to Expert options, find the UpdateMethod variable, and switch it to 0 or 1. I am fairly confident the setting of 1 is less resource intensive than 0, so I went with it.

image

My Java programs are fixed and redrawing fine now.

 
  • Share/Save/Bookmark

Updated: June 9th, 2009

Introduction

If you, like me, are building or thinking of implementing a MySQL-powered application that has any need for prioritizing selecting certain data over other data, this article is for you.

Example

As a real world example, consider a queue-like video processing system. Your application receives new videos and processes them. The volume of incoming videos can at times be higher than the processing rate because the process is CPU bound, so occasionally a pretty long queue may form. You will try to process them as fast as you can but…

Note that I am using a queue here, so the the next item to be processed is a result of sorting by some sort of field in a ascending order, for example ORDER BY id or ORDER BY upload_date. I’ll pick the id sort here.

…suddenly, you need to process a video somewhere in the middle of the queue or an important video enters and needs immediate attention. What do you do?

An obvious solution is implementing a simple priority system where each item has a numeric priority field. Now you can sort first by priority from highest to lowest and then by id within the highest priority. Important and urgent items get a their priority changed to something higher and get processed first. There is only one problem.

Problem

The problem is pretty serious – let’s take a look at the SELECT statement. Before selecting, I’ve added 19 random rows to have some data to work on.

SELECT * FROM queue ORDER BY priority DESC, id LIMIT 1;

What kind of index would you put on this table to speed up this query? You do want to add a proper index, don’t you? DO YOU? Ok, good.

 

Here’s what happens without any indexes:

mysql> EXPLAIN SELECT * FROM queue ORDER BY priority DESC, id LIMIT 1;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | queue | ALL  | NULL          | NULL | NULL    | NULL |   19 | Using filesort | 
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

Using filesort, ugh, of course, due to sorting without an index.

 

Let’s see, how about a combined index on (priority, id)?

mysql> ALTER TABLE `queue` ADD INDEX `priority_id`(`priority`, `id`);
Query OK, 19 rows affected (0.05 sec)
Records: 19  Duplicates: 0  Warnings: 0
 
mysql> EXPLAIN SELECT * FROM queue ORDER BY priority DESC, id LIMIT 1;
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------------+
| id | select_type | table | type  | possible_keys | key         | key_len | ref  | rows | Extra                       |
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | queue | index | NULL          | priority_id | 5       | NULL |   19 | Using index; Using filesort | 
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

Better because an index is being used but not very good because filesort is still present. “Of course!”, you slap yourself on the forehead. The first ORDER BY uses a DESCENDING order, and our key is in ASCENDING order.

 

So, let’s add the proper key with the right ordering instead.

mysql> ALTER TABLE `queue` DROP INDEX `priority_id`;
Query OK, 19 rows affected (0.05 sec)
Records: 19  Duplicates: 0  Warnings: 0
 
mysql> ALTER TABLE `queue` ADD INDEX `priority_id`(`priority` DESC, `id`);
Query OK, 19 rows affected (0.06 sec)
Records: 19  Duplicates: 0  Warnings: 0
mysql> EXPLAIN SELECT * FROM queue ORDER BY priority DESC, id LIMIT 1;
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------------+
| id | select_type | table | type  | possible_keys | key         | key_len | ref  | rows | Extra                       |
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | queue | index | NULL          | priority_id | 5       | NULL |   19 | Using index; Using filesort | 
+----+-------------+-------+-------+---------------+-------------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

What the deuce? This is the same result as with the previous index. Time to dig up the documentation.

 

Here is what the MySQL manual has to say under the ORDER BY optimization section:

MySQL cannot use indexes to resolve the ORDER BY, although it still uses indexes to find the rows that match the WHERE clause … if you mix ASC and DESC:

SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;

Moreover, to confuse the user even more, the index creation command accepts the DESC instruction, without actually honoring it, as specified in the CREATE INDEX section:

An index_col_name specification can end with ASC or DESC. These keywords are allowed for future extensions for specifying ascending or descending index value storage. Currently, they are parsed but ignored; index values are always stored in ascending order.

So, after so many years MySQL still doesn’t support such basic functionality – you are either stuck with a query that uses filesort or have to look for a workaround.

Solution

Since it’s not possible to mix order directions, the solution is then to change the meaning of the priority column to match your needs. Thus, in the new approach priority 1 is higher than priority 10, and the application logic needs to accommodate to that. If you caught this while the application is still young, the code may be easy to change, but otherwise it could be a major pain in the butt.

Conclusion

The moral here is: plan your queries ahead and don’t mix and match DESC and ASC ordering as MySQL will not be able to use an index to resolve it. Do it even sooner if you’re putting lots and lots of data into your tables.

 
  • Share/Save/Bookmark

So the other day I was setting up public key authentication for one of my users, which is usually very straightforward: generate a private/public key pair, stick the private key into user's .ssh dir, set dir permissions to 0700, private key permissions to 0600, stick the public key into the authorized_keys file on the server, and the job's done. However, this time, no matter what I was doing, the public key was being rejected or ignored and the system was moving on to the keyboard-interactive authentication.

Debugging on the client side with -v didn't help much:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
artem@DeathStar:~/svn/b2/Fetch/LinkChecker> ssh -v monkey@192.168.1.30
OpenSSH_4.6p1, OpenSSL 0.9.8e 23 Feb 2007   
...
lots of boring shit
...
debug1: Found key in /home/artem/.ssh/known_hosts:1
debug1: ssh_rsa_verify: signature correct
...
more boring shit
...
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Next authentication method: publickey
debug1: Offering public key:
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Offering public key:
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Offering public key: /home/artem/.ssh/id_rsa
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Trying private key: /home/artem/.ssh/id_dsa
debug1: Next authentication method: keyboard-interactive
Password:

After breaking my head over possible reasons why the pile of junk that thinks it's smarter than me next to my feet doesn't work, kicking it a few times, and observing the same result, I turned to debugging the ssh daemon itself - sshd.

  • The -d option disables the daemon mode and enables debug mode, in which only 1 connection is accepted for the lifetime of the server, after which it simply quits.
  • -dd simply enables a more detailed output.
  • -e switches this debug output from a log file to STDOUT.

However, to free up port 22, I had to stop the daemon that was already running, or else a "Bind to port 22 on 0.0.0.0 failed: Address already in use." error appeared (duh). An interesting question though, especially for people doing this to remote boxes, what happens when one stops sshd? Ever thought of doing that but instead ran over to your mommy crying like a little girl? Well, fear no more, because I'll tell you exactly what happens:

  1. New users will have their connection refused.
  2. Your own connection will not be interrrupted. sshd works by spawning a new instance of itself for every incoming connection, so your own sshd process will stay in memory.

So where was I?

1
/usr/sbin/sshd -dd -e
1
2
3
4
...
Authentication refused: bad ownership or modes for directory /home/monkey
...
Failed publickey for monkey from 192.168.1.30 port 56287 ssh2

AhA!! (emphasis on the last 'a'). What have we here?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
artem@DeathStar:~> cd /home/
artem@DeathStar:/home/> l
drwxrwx--- 29 monkey  users 4096 2008-08-06 23:14 monkey/
 
DeathStar:/home/ # chmod 755 monkey
drwxr-xr-x 29 monkey  users 4096 2008-08-06 23:14 monkey/
 
artem@DeathStar:~/svn/b2/Fetch/LinkChecker> ssh -v monkey@192.168.1.30
OpenSSH_4.6p1, OpenSSL 0.9.8e 23 Feb 2007   
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to 192.168.1.30 [192.168.1.30] port 22.
debug1: Connection established.
debug1: identity file /home/artem/.ssh/id_rsa type 1
debug1: identity file /home/artem/.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_4.6
debug1: match: OpenSSH_4.6 pat OpenSSH*
...

Connection established, all systems are go, the key has been accepted.

Inspired by http://linux.derkeiler.com/Mailing-Lists/Fedora/2005-08/1105.html

P.S. Don't forget to /etc/init.d/sshd start. ;)

 
  • Share/Save/Bookmark

Apparently it's not straightforward to install SOAP::Lite, even using CPAN.

Check this out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cpan[1]> install SOAP::Lite
CPAN: Storable loaded ok (v2.18)
Going to read /root/.cpan/Metadata
  Database was generated on Tue, 29 Apr 2008 18:29:45 GMT
CPAN: YAML loaded ok (v0.66)
Going to read /root/.cpan/build/
............................................................................DONE
Found 149 old builds, restored the state of 109
Warning: Cannot install SOAP::Lite, don't know what it is.
Try the command
 
    i /SOAP::Lite/
 
to find objects with matching identifiers.
CPAN: Time::HiRes loaded ok (v1.9713)

Huh? Okay…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cpan[2]> i /SOAP::Lite/    
Module    ResourcePool::Command::SOAP::Lite::Call (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz)
Module    ResourcePool::Factory::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz)
Module    ResourcePool::Resource::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz)
Module    SOAP::Lite::Deserializer::XMLSchema1999 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module    SOAP::Lite::Deserializer::XMLSchema2001 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module    SOAP::Lite::Deserializer::XMLSchemaSOAP1_1 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module    SOAP::Lite::Deserializer::XMLSchemaSOAP1_2 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module    SOAP::Lite::InstanceExporter (SMEISNER/SOAP-Lite-InstanceExporter-0.02.tar.gz)
Module    SOAP::Lite::Packager   (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module    SOAP::Lite::Simple     (LLAP/SOAP-Lite-Simple-1.9.tar.gz)
Module    SOAP::Lite::Simple::DotNet (LLAP/SOAP-Lite-Simple-1.4.tar.gz)
Module    SOAP::Lite::Simple::Real (LLAP/SOAP-Lite-Simple-1.4.tar.gz)
Module    SOAP::Lite::Utility    (BRYCE/SOAP-Lite-Utility-0.01.tar.gz)
Module    SOAP::Lite::Utils      (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
14 items found

Wtf? Let's try something else.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
cpan[8]> i /SOAP.*Lite/                           
Distribution    BRYCE/SOAP-Lite-Utility-0.01.tar.gz
Distribution    BYRNE/SOAP/SOAP-Lite-0.60a.tar.gz
Distribution    DYACOB/SOAP-Lite-ActiveWorks-0.10.tar.gz
Distribution    DYACOB/SOAP-Lite-SmartProxy-0.11.tar.gz
Distribution    LLAP/SOAP-Lite-Simple-1.4.tar.gz
Distribution    LLAP/SOAP-Lite-Simple-1.9.tar.gz
Distribution    MKUTTER/SOAP-Lite-0.71.04.tar.gz
Distribution    MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz
Distribution    SMEISNER/SOAP-Lite-InstanceExporter-0.02.tar.gz
Module    Catalyst::Action::SOAP::DocumentLiteral (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz)
Module    Catalyst::Action::SOAP::DocumentLiteralWrapped (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz)
Module    Catalyst::Action::SOAP::RPCLiteral (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz)
Module    Catalyst::Controller::SOAP::DocumentLiteralWrapped (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz)
Module    Net::DRI::Transport::HTTP::SOAPLite (PMEVZEK/Net-DRI-0.85.tar.gz)
Module    ResourcePool::Command::SOAP::Lite::Call (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz)
Module    ResourcePool::Factory::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz)
Module    ResourcePool::Resource::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz)
Module  = SOAP::Lite::Deserializer::XMLSchema1999 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module  = SOAP::Lite::Deserializer::XMLSchema2001 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module  = SOAP::Lite::Deserializer::XMLSchemaSOAP1_1 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module  = SOAP::Lite::Deserializer::XMLSchemaSOAP1_2 (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module    SOAP::Lite::InstanceExporter (SMEISNER/SOAP-Lite-InstanceExporter-0.02.tar.gz)
Module  = SOAP::Lite::Packager   (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
Module    SOAP::Lite::Simple     (LLAP/SOAP-Lite-Simple-1.9.tar.gz)
Module    SOAP::Lite::Simple::DotNet (LLAP/SOAP-Lite-Simple-1.4.tar.gz)
Module    SOAP::Lite::Simple::Real (LLAP/SOAP-Lite-Simple-1.4.tar.gz)
Module    SOAP::Lite::Utility    (BRYCE/SOAP-Lite-Utility-0.01.tar.gz)
Module  = SOAP::Lite::Utils      (MKUTTER/SOAP-Lite-0.71.04.tar.gz)
28 items found

Aha! It's hiding under a Distribution. Tricky, tricky.

1
2
cpan
install MKUTTER/SOAP-Lite-0.71.04.tar.gz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  CPAN.pm: Going to build M/MK/MKUTTER/SOAP-Lite-0.71.04.tar.gz
 
We are about to install SOAP::Lite and for your convenience will provide
you with list of modules and prerequisites, so you'll be able to choose
only modules you need for your configuration.
 
XMLRPC::Lite, UDDI::Lite, and XML::Parser::Lite are included by default.
Installed transports can be used for both SOAP::Lite and XMLRPC::Lite.
 
Press  to see the detailed list.  
 
Feature                       Prerequisites                Install?
----------------------------- ---------------------------- --------
Core Package                  [*] Scalar::Util             always  
                              [*] Test::More                       
                              [*] URI                              
                              [*] MIME::Base64                     
                              [*] version                          
                              [*] XML::Parser (v2.23)              
Client HTTP support           [*] LWP::UserAgent           always  
Client HTTPS support          [*] Crypt::SSLeay            [ yes ] 
Client SMTP/sendmail support  [ ] MIME::Lite               [ no ]  
Client FTP support            [*] IO::File                 [ yes ] 
                              [*] Net::FTP                         
Standalone HTTP server        [*] HTTP::Daemon             [ yes ] 
Apache/mod_perl server        [ ] Apache                   [ no ]  
FastCGI server                [ ] FCGI                     [ no ]  
POP3 server                   [*] MIME::Parser             [ yes ] 
                              [*] Net::POP3                        
IO server                     [*] IO::File                 [ yes ] 
MQ transport support          [ ] MQSeries                 [ no ]  
JABBER transport support      [ ] Net::Jabber              [ no ]  
MIME messages                 [*] MIME::Parser             [ yes ] 
DIME messages                 [*] IO::Scalar (v2.105)      [ no ]  
                              [ ] DIME::Tools (v0.03)              
                              [ ] Data::UUID (v0.11)               
SSL Support for TCP Transport [ ] IO::Socket::SSL          [ no ]  
Compression support for HTTP  [*] Compress::Zlib           [ yes ] 
MIME interoperability w/ Axis [ ] MIME::Parser (v6.106)    [ no ]  
--- An asterix '[*]' indicates if the module is currently installed.
 
Do you want to proceed with this configuration? [yes] 
Checking if your kit is complete...
Looks good
Writing Makefile for SOAP::Lite
cp lib/SOAP/Packager.pm blib/lib/SOAP/Packager.pm
cp lib/XML/Parser/Lite.pm blib/lib/XML/Parser/Lite.pm
...
Writing /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/SOAP/Lite/.packlist
Appending installation info to /usr/lib/perl5/5.10.0/i686-linux/perllocal.pod
  MKUTTER/SOAP-Lite-0.71.04.tar.gz
  /usr/bin/make install  -- OK

The latest version of SOAP::Lite is installed, time to pat yourself on the back and write some code to actually use it.

 
  • Share/Save/Bookmark

I'm sure most Perl coders have to face this annoying problem at one point or another: how do you consistently get the return value out of a system call, be at executed via backticks or system()? Backticks return the output of the program with no error code in sight, while system() returns the error code but prints the output instead of putting it into a variable.

The best solution I could find to this problem to date was posted at http://www.perlmonks.org/?node_id=19119 and involved opening a piped filehandle. It worked quite well but always felt like a hack (which it was). Having used the new Perl 5.10 for a few months, I was shocked today to find this new variable that I've been dreaming about for years:

1
${^CHILD_ERROR_NATIVE}

This variable gives the native status returned by the last pipe close, backtick command, successful call to wait() or waitpid(), or from the system() operator. See perlrun for details. (Contributed by Gisle Aas.)

http://search.cpan.org/dist/perl-5.10.0/pod/perl5100delta.pod#New_internal_variables

I've just tested it and it works as described. Finally!.. what else can I say?

 
  • Share/Save/Bookmark