hits counter

Tech Talk


Personal and Tech Talk30 Nov 2009 07:56 am

The past few weeks have been a bit intense with work and personal projects, I’ve been at the keyboard quite a far bit to get my first real app out. I’ll have another post later on, closer to the date when I can actually release it. Of course, it won’t be the cleanest release, but there will be regular updates (in fact that means I need an updating mechanism which will make life easier for the people who do end up using the software). I’ve spent a bit of time refactoring my current project before I started the new tasks. I felt that there was a bit of code smell and well as performance issues. One simple example would be to create a local instance for any values which are calculated within loops.

dim a(100) as string
for i = 0 to Ubound(a)
	//do something
next

Instead of doing that, it would make the loop just a tad bit faster by creating j to be the value of Ubound(a) UNLESS of course, you are changing the length of the array within the loop itself (which I then recommend at least changing the for loop from going “to” to “downto”. This step also allows for you to run through the debugger and find out what j is at that particular time.

dim a(100) as string
dim i as integer = 0
dim j as integer = Ubound(a)
for i = 0 to j
	//do something
next

OR if you are changing the number of elements to the array

dim a(100) as string
dim i as integer = 0
dim j as integer = Ubound(a)
for i = j  downto 0
	if a(i) <> nil then
		if a(i) <> "aaa" then
			a(i).remove
		end
	end
next

I’ve got an app which demonstrates small changes to your code which will improve your performance (if you haven’t adopted these practices already). I used it as a demonstration at work and it is similar to what was presented at the REALBasic Summit. I’ll upload that in time.

I’ve just put down a deposit to get a new mountain bike (Kona Caldera 2009 model) from the Bike Barn out at Paramatta. They were having a sale on Kona 09 models and so I picked it up for $1000. I’ll get it at the end of the work and give it a work out then.

Written by Milton Lai

Tech Talk29 Sep 2009 12:24 pm

This summit ran between the 24th and 26th of September. Hosted by InspiringApps in conjunction with ARBP and held in Boulder, Colorado. This town is a great place to visit, especially when you’re into anything outdoors (except for surfing – although there was a surfing diner somewhere in Boulder).
The sessions that ran were all quite relevant to almost everything that I do, and of course, some more than others.

psrb01
The view from St. Julien Hotel & Spa.

psrb12
InspiringApps

psrb02
Reporting Tools, Options, and Techniques – Bob Keeney

psrb03
Cocoa and Reporting Features in REALbasic – Geoff Perlman

psrb04
SQLite Power Tools – Ryan Vail

psrb05
OO Database Framework and Introspection – Seth Verrinder

psrb06
Profiling and Performance Tweaking – Joe Strout

psrb07
Version Control, And Why it Rocks – Aaron Gerber and Mathias Gran

psrb09
Building REALbasic Plugins – Christian Schmitz

psrb10
Usability & Design Techniques – Jay Crain

psrb11
Facilitated RB/RS/Summit Feedback Session – Brad Weber

psrb13
The few remaining members on the final day up in Estes Park.
Milton Lai, Seth Verrinder, Frederick W. Roller, Rick, Gerard Hammond, Bob Keeney, Norman Palardy

Written by Milton Lai

Tech Talk14 Sep 2009 02:57 pm

I ran into an issue at the end of last week regarding sessions in PHP. The problem was the locking that happens over the sessions. This isn’t what’s now coded in place, but it was a thought I had (bad idea). So I had a PHP file which did a POST to another file – using the following code

function do_post_request($url, $data, $optional_headers = null) {
	$params = array('http' => array('method' => 'POST','content' => $data));
	if ($optional_headers !== null) {
		$params['http']['header'] = $optional_headers;
	}
	$ctx = stream_context_create($params);
	$fp = fopen($url, 'rb', false, $ctx);
	if (!$fp) {
		throw new Exception("Problem with $url, $php_errormsg");
	}
	$response = stream_get_contents($fp);
	if ($response === false) {
		throw new Exception("Problem reading data from $url, $php_errormsg");
	}
	return $response;
}

Original Source

The receiving page will start off its own session and to try to access the globals in the original session, I tried assigning the sessionid to the new page before calling session_start();.

session_id($_GET['SESSIONID']);
session_start();

What happens is the first page will take a long while before timing out. Behind the scenes, the first PHP page is WAITING for the POST to return, whilst having locked the session variables as already being accessed. The receiving page then tries to “resume” this session and starts to wait for the session variables to be unlocked before so they can be read.
There is the ability to call session_write_close() but this will set the session variables to read only and you will not be able to write to them.

PHP.net user comment

Written by Milton Lai

Tech Talk03 Sep 2009 07:05 pm

I’ve implemented a web service for work which allows you to queue a job, and also to retrieve the job. I also implemented a simple login header which looks after your session through the database. The long term issue that we’ve had in the past is that Safari drops the session (thus losing all global session variables) and also Safari dropping the ability to kill the session in PHP. So I’ve made a simple module which is included on all PHP pages and it sorts out the authentication for you.

The problem came when I tried to introduce this login header to the top of my webpage which “GET”’s the job. The normal process of forcing a user to download the contents is to use the following code:

<\?php
     header("Cache-Control: public");
     header("Content-Description: File Transfer");
     header("Content-Disposition: attachment; filename=test.txt");
     header("Content-Type: text/plain");
     echo($streamOfText);
     //or
     //readfile("test");
?>

The problem with doing that is if you have other text sitting on that page (or just include ‘login.php’;), since the header forces ALL content to be saved into the file test.txt, and not just $streamOfText.

What I ended up doing to get around this issue, might be a long way to solve the issue, but it works just fine. I created a file in the same disc space and filled it in with the header information as well as reading in another file on the disc. I created the other file with the contents of $streamOfText. At the end of the first file, I unlink the content file as well as itself. The original GET file does a simple header redirect. This leaves no traces of those files ever being created or existing.

JobHandler
	$fp = fopen($JobID . ".php", 'w');
	fwrite($fp, "<\?php " . "\n");
	fwrite($fp, 'header("Cache-Control: public");' . "\n");
	...
	fwrite($fp, "\$filename='" . $JobID . "';" . "\n");
	fwrite($fp, "readfile(\$filename);" . "\n");
	fwrite($fp, "unlink(\$filename);" . "\n");
	fwrite($fp, "unlink(\$JobID . '.php');" . "\n");
	fwrite($fp, "?>" . "\n");
	fclose($fp);

	header('Location:'.$JobID . ".php");

Note: Just clicked on “preformatted” as a markup in MarsEdit and it lets me write code! Very handy, since I tried doing it last time, with all sorts of funny things happening!

Written by Milton Lai

Tech Talk13 Mar 2009 06:54 pm

This has been one of those user functionalities which I attacked sometime last year and now that I’ve had it placed into the framework, I feel that its been tested and works quite well. The frustration I had with listboxes where you do a sort (lets take iTunes for example) on Artist and lets say you know the name of the song. The list of the titles is in some random (or possibly the date added) order. What I’ve wanted to do, is to sort on the title, but to keep the artist sort. Its the same thing as doing a database query and using “order by artist, title”.

The following code is written in RealBasic and is by no means syntactically correct. Its only to show how it can be done.


lastString = me.cell(1, lastSortedColumn)

for i = 1 to me.listcount - 1
compareString = me.Cell(i, lastSortedColumn)

if lastString <> compareString then
self.Sort(lastPOS, i - 1)
lastPOS = i
lastString = me.Cell(lastPOS, lastSortedColumn)
end
next

The implementation most probably isn’t the fastest, but I haven’t noticed any speed issues with it yet. The idea is that you should know which column you’ve sorted on (lastSortedColumn), and when holding down a key, like the command key, to run through your listbox and sort the rows where the artists are the same. Its not difficult to do, and is a big time saver.

Written by Milton Lai

Next Page »