Odi's astoundingly incomplete notes
New entriesCode
back | nextLayer popups vs. Window popups
It has become very popular to use JavaScript to create modal dialogs and popups "in-page". That means they are overlayed over the content of the webapp window. Before this trend, the standard way to show a popup dialog was in a new window.
Anybody who implements JavaScript popup layers PLEASE make sure not to break the usability that a normal popup window has:
Similarly when you provide a scrollable widget in JavaScript, make sure it behaves like a normal scroll bar: support cursor up/down, page up/down and the scroll wheel.
Similarly when you create a smart text input, make sure it supports everything a stupid standard text box does: ctrl-z for undo typing, cursor, home/end, shift select ranges, etc.
Anybody who implements JavaScript popup layers PLEASE make sure not to break the usability that a normal popup window has:
- Add a close button: Something will always go wrong and your fancy layer will not close correctly. This leaves the user with a broken application. His only option is to close the browser window, or reload the page. Give back some power to the user and let hime close the popup with a simple button. Place this button in the titlebar. Careful: different platforms have varying standards where they place their close buttons. You may not be able at all to detect this standard automatically (Linux desktops are configurable and can put these buttons almost anywhere on a window decoration).
- Make it movable: Popups hide content underneath. Sometimes the user may want to read information that is hidden by the popup. A movable popup lets him move the thing out of the way if necessary.
- Implement the standard keyboard shortcuts: Some people are used to confirm popups with the Enter, Space, Esc, TAB component navigation or other keyboard shortcuts. Careful: different platforms may have different standards.
- Allow copy/paste: If the popup contains form fields, make sure that copy/paste still works -- on all browsers. Some fancy editors break it badly.
- If the window is already open, make sure to bring it to front (focus).
- Make it a "dependent" window, so that it automatically closes if the user navigates away or closes the parent window.
Similarly when you provide a scrollable widget in JavaScript, make sure it behaves like a normal scroll bar: support cursor up/down, page up/down and the scroll wheel.
Similarly when you create a smart text input, make sure it supports everything a stupid standard text box does: ctrl-z for undo typing, cursor, home/end, shift select ranges, etc.
Add comment
Campaign for less configuration
I am currently cracking down on the amount of configuration of our product. Join the campaign and do the same for YOUR product:
- Define sensible default values for all parameters, thus eliminating the need to override them.
- Find configuration that is the same (nearly) everywhere and make that value the default. Then make the parameter optional.
- Identify parameters that have only one legal value. Treat like above or eliminate the parameter altogether. During a phase of backwards-compatibility warn if the parameter is set and tell the user to remove it.
- Complex object trees assembled with tools like Spring Beans can maybe hardcoded and produced by a factory, if feasible.
- If you want to go extreme, make the system smart to assume sensible default values at runtime, if they are not present in the configuration, and log the assumptions and decisions taken.
- Define required filenames or filename patterns instead of configuring them.
- Use a fixed package name, tagging interfaces or annotations and reflection to find a class dynamically at runtime instead of configuring its classname.
- Deduce class names from a context instead of mapping some property to classes in a configuration file.
Migration from x86 to x86_64
If you happen to run your system on x86 and would like to switch to x86_64 (amd64) you are lucky when running Gentoo. With Gentoo this little circus trick is not very hard to to. The best thing is, while you do this you can continue working in your old environment. So downtime is negligible.
Executable file formats > IA32 Emulation (
It's very common to enable this option. The interesting part is: There is no reason why such a kernel shouldn't execute 32bit programs ONLY. That means such a kernel will happily boot and run any ordinary x86 userland!
So why not compile ourselves an x86_64 kernel on our x86 system. Unfortunately our gcc compiler can not produce x86_64 binaries. Only x86 code. So we need to cross-compile.
After unpacking the stage3 tarball, you must carefully merge files and directories from
Then mount proc and dev, chroot and compile away. You probably want to emerge all packages in your original
Before you reboot, reinstall grub!
x86_64 boots x86
As you know an x86_64 kernel has an option to execute 32-bit programs:Executable file formats > IA32 Emulation (
IA32_EMULATION
in .config)It's very common to enable this option. The interesting part is: There is no reason why such a kernel shouldn't execute 32bit programs ONLY. That means such a kernel will happily boot and run any ordinary x86 userland!
So why not compile ourselves an x86_64 kernel on our x86 system. Unfortunately our gcc compiler can not produce x86_64 binaries. Only x86 code. So we need to cross-compile.
Toolchain
Fortunately this is no rocket science, and a fairly common thing these days. In our case, all it takes is typing in two commands and waiting a bit:emerge -av crossdev crossdev -S -s1 --target x86_64-pc-linux-gnuThis installs the crossdev package and creates a minimal toolchain to cross-compile the kernel.
Configuring the x86_64 kernel
Make a copy of your existing kernel tree (or emerge gentoo-sources) into /usr/src/amd64:cd /usr/src cp -ra linux amd64 # clean up cd amd64 make mrproper # copy over the config cp ../linux/.config . # alternatively obtain it from the running kernel cp /proc/config.gz . gunzip config.gz mv config .configNow we are ready to configure our kernel. This is quite easy as the options for x86_64 are not much different. Just answer all the questions that the script asks you. The makefile will use our existing config as a template, so you will end up with basically the same kernel that you are already running. All we have to do is tell make that we want to configure for a different architecture:
make ARCH="x86_64" oldconfig # now compile (mind the trailing dash after gnu) make ARCH="x86_64" CROSS_COMPILE="x86_64-pc-linux-gnu-" make ARCH="x86_64" CROSS_COMPILE="x86_64-pc-linux-gnu-" installAdd a new entry in your boot loader and reboot.
Installing the new system
Your system should come up like before. Only that you are now running a full x86_64 kernel! This enables you to execute 64-bit binaries. You can install an amd64-Gentoo into a subdirectory (chroot) as if it was a new system. Just be careful not to accidentially change files outside of this subdirectory! When done you can do the switch and stuff your existing root into some subdirectory, then move your new Gentoo in place.After unpacking the stage3 tarball, you must carefully merge files and directories from
/etc
and /var
to the new root. Take special care of the HOST
variable in /etc/make.conf
! You should copy over everything from /usr/local
and check /opt
. But keep /root
and /home
(you can just leave them in place them when doing the switch). You should NOT copy over /var/db/pkg
, /var/cache
, /var/lib/portage
and /var/cache
.Then mount proc and dev, chroot and compile away. You probably want to emerge all packages in your original
/var/lib/portage/world
file.Before you reboot, reinstall grub!
And now gettimeofday() no longer rolls in the year 2038. Yay!
In my mind this is the single most important reason to upgrade to x86_64.
That's why:
typedef long __kernel_time_t;
x86: sizeof(long) = 4
x86_64: sizeof(long) = 8
In my mind this is the single most important reason to upgrade to x86_64.
That's why:
typedef long __kernel_time_t;
x86: sizeof(long) = 4
x86_64: sizeof(long) = 8
> In my mind this [linux x86 Year 2038 bug] is the single most important reason to upgrade to x86_64.
Yeah, start upgrading in 2036, to be on the safe side ... ;-)
Yeah, start upgrading in 2036, to be on the safe side ... ;-)
I followed instructions successfully but...when I reboot, it stats to boot on the x86_64 kernel but it stops during boot process (after USB detection). If I wait enough longer, I got a message saying that task has not answered during at least 120 seconds...
any idea ?
Thanks
Alex
any idea ?
Thanks
Alex
...I answer to myself... you have to disable the Enable loadable module support option to compile all modules internaly...and you have to enable IA32 emulation support... and it works ! ;-)
Thanks for the instructions. I used them and they worked very well.
Thanks again
Thanks again
Find ebuild by filename
The Portage File List (PFL) is a project that does some useful reverse-engineering in portage. Sometimes you want to install a specific system utility (e.g. iwconfig, host) or library and just can't figure out which ebuild to install. This is when the PFL comes in handy.
It collects portage database from Gentoo users and stores them in its database. Users can query the DB online to find the right ebuild given a filename. Unfortunately the project is not widely known. Probably due to the fact that it doesn't have a front page that explains what it is.
NB: You don't need the PFL if you just want to figure out which ebuild has installed a specific file on your system. The command equery can figure that out from your local portage database:
It collects portage database from Gentoo users and stores them in its database. Users can query the DB online to find the right ebuild given a filename. Unfortunately the project is not widely known. Probably due to the fact that it doesn't have a front page that explains what it is.
NB: You don't need the PFL if you just want to figure out which ebuild has installed a specific file on your system. The command equery can figure that out from your local portage database:
equery b /usr/bin/iwconfig
Installing Oracle 11g on x86_64 Gentoo
The normal quick install guide applies. Additionally:
Oracle needs some 32bit versions of packages. So we need to use the abi_x86_32 USE flag on some packages.
Set USE flags in
1. emerge the following packages:
4.
5. /etc/sysctl.conf: Always overcommit seems to be the only working solution with dozens of GB SGA.
6. If remote installing:
7. On link errors during install (or during copying files in a different shell if you are quick), edit
In
8. Disable password expiry
9. Enable automatic startup in
10. Add an init script
See also Gentoo forum entry.
Oracle needs some 32bit versions of packages. So we need to use the abi_x86_32 USE flag on some packages.
Set USE flags in
/etc/portage/package.use
:
- dev-libs/libaio abi_x86_32
/etc/portage/package.keywords
:
- =app-shells/ksh-93.20140606
1. emerge the following packages:
- ksh
- rpm
- xdpyinfo
- libaio
- sysstat
- elfutils
- ln -s /usr/bin/rpm /bin/rpm
- ln -s /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.5/libgcc_s.so.1 /lib64/libgcc_s.so.1
- ln -s /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.5/libstdc++.so.6 /usr/lib/libstdc++.so.6
- ln -s /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.5/32/libgcc_s.so.1 /lib32/libgcc_s.so.1
- ln -s /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.5/32/libstdc++.so.6 /usr/lib32/libstdc++.so.6
/bin/gcc
wrapper script:
#!/bin/bash if [ "$1" = "-m32" ]; then /usr/bin/gcc -L/usr/lib32 $* else /usr/bin/gcc $* fiand make it executable:
chmod 755 /bin/gcc
4.
/dev/shm
mount options need to be default and the size needs to be set to accomodate your SGA. NB that more shm is required than the size of your SGA. This seems to be due to busg in Oracle. The required additional space can be a lot. To be safe, just set it to all available memory:/etc/fstab
:shm /dev/shm tmpfs defaults,size=64g 0 0Then:
mount -o remount,defaults,size=64g /dev/shm
5. /etc/sysctl.conf: Always overcommit seems to be the only working solution with dozens of GB SGA.
# there is no swap really vm.swappiness=0 # 0: default overcommit # 1: always overcommit # 2: never overcommit. max = swap + ratio% * RAM vm.overcommit_memory=1 # commit limit = (swap + ratio% * RAM) vm.overcommit_ratio=100 # Oracle fs.aio-max-nr = 1048576 fs.file-max = 6815744 kernel.shmall = 2097152 kernel.shmmax = 5368709120 kernel.shmmni = 4096 kernel.sem = 250 32000 100 128 net.ipv4.ip_local_port_range = 9000 65500 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 1048586Then
sysctl -p
6. If remote installing:
- /etc/ssh/sshd_config: X11Forwarding yes
- use
ssh -Y user@host
./runInstaller -ignoreSysPrereqs
7. On link errors during install (or during copying files in a different shell if you are quick), edit
$ORACLE_HOME/lib/sysliblist
and add -lrt
In
$ORACLE_HOME/sysman/lib
run manually make -f ins_emagent.mk "agent"
then copy the last failed gcc commandline and add -lnnz11
and execute it. Hit the Retry button.8. Disable password expiry
9. Enable automatic startup in
/etc/oratab
by setting the last column to Y
.10. Add an init script
/etc/init.d/oracle
:
#!/sbin/runscript depend() { need net logger hostname clock after sshd } start() { ebegin "Oracle" cat <<-"EOF"|su - ${ORACLE_OWNER:-oracle} lsnrctl start dbstart emctl start dbconsole EOF eend $? } stop() { ebegin "Oracle" cat <<-"EOF"|su - ${ORACLE_OWNER:-oracle} emctl stop dbconsole dbshut lsnrctl stop EOF eend $? }11. If running without swap, make sure to size the SGA appropriately.
See also Gentoo forum entry.
Thread.isInterrupted() broken
Thread.isInterrupted() is broken on many recent JDKs (on JDK 1.5.0_16..20, 1.6.0_10..16). The bug has been fixed in the latest releases. This is quite a bad bug and may affect many applications. As a developer you don't expect these fundamental things to break, and it's scary when they do. If your application relies on this to work, you may want to blacklist these JDKs and refuse to run.
Word 2007 hangs at startup waiting for network printer
Often happens to me (in the office, only place where I use Windows) when I am in a VPN and want to open a Doc. I only have network printers. No local one. Solution? Add a PostScript printer (use a HP Color Laserjet PS driver) and set its port to FILE. Set this as the default printer. This one is always available and thus Word doesn't hang itself waiting for it.
no more DJB dnscache
Until today I was running DJB's dnscache in my LAN. Today I switched to PowerDNS recursor. The reason was that I experienced strange resolving problems with dnscache. At some point the cache would sometimes indicate a lame delegation from certain domains, such as
So I rather chose an implementation that is widely used today and works with the real DNS.
akmai.net
. Sometimes even from a TLD such as .uk
! The problem went away once dnscache was restarted. So it must be some bug. All in all the dnscache makes the impression that its developer doesn't really care about the real world, but rather implemented it to the letter of the spec. So his focus was not to provide an implementation that works out in the wild, but rather tries to educate people how to use DNS. Unfortunately this "education" happens on the wrong end here.So I rather chose an implementation that is widely used today and works with the real DNS.
Why guessing is bad
Fine JavaScript example:
yields 2 on FireFox 3.5, 0 on IE8 and Chrome, and 8 on Opera.
Background: parseInt interpretes a number with a leading zero in octal (not decimal). 08 is not a legal octal value however.
The problem here is not so much that all platforms behave differently. But that none of them actually spots theobvious error and throws an exception. So all the implementations just make a wild guess and return a wrong value (any value is wrong for an invalid input)! This is bad for the developer as it prevents bugs from being discovered.
alert(parseInt("08"));
yields 2 on FireFox 3.5, 0 on IE8 and Chrome, and 8 on Opera.
Background: parseInt interpretes a number with a leading zero in octal (not decimal). 08 is not a legal octal value however.
The problem here is not so much that all platforms behave differently. But that none of them actually spots the
Table lock on delete
I just found out about a weird behaviour of Oracle: if you delete a parent record and the child's foreign key is not indexed, Oracle will use a Full Table Lock instead of a Row Lock! It's very easy to trigger deadlocks like this. So make damn sure that all your foreign keys are indexed, even if the tables have only two rows. It's something that's easy to forget. Otherwise transactions may contend for the same lock even if they touch a completely different set of records.
back
|
next
you are amazing! thanks for your note it has saved my day (more like a week... you know ;)