Archive

Posts Tagged ‘php’

Timing Out PHP Soap Calls

October 21st, 2009 11 comments

So I’ve got an interesting technical post for you today. I know I don’t normally post technical things here on my blog, but I felt this was such an interesting exercise in triumphing over a big issue here at work that I wanted to post about it.

We call several third-party vendors for web-based services in my department. We’re really keen on keeping transaction times low, so we have a set timeout for each vendor to ensure we don’t wait too long. Most of our vendor calls are Curl calls, but we have a couple that use Soap.

Curl has built-in functionality to enable a timeout. PHP’s internal Soap library does not. Thus, PHP’s documentation says to enable the following to set a limit on Soap calls:

ini_set("default_socket_timeout", 5); // 5 seconds

This is all fine and dandy. Or, at least, I thought it was. When we first had an outage with one Soap-based vendor, this timeout mechanism worked correctly. However the second time, it did not. We still waited up to 60 seconds for the call despite our code having not changed. Highly distressing is the word.

I researched this issue at great length, and used one of our own Soap services to test out a theory. I put this into the code:

ob_implicit_flush();
echo " ";
sleep(15);

The ob_implicit_flush() function call forces PHP to send any output as it immediately becomes available. Normally, PHP sends it all at the close of the script, or if you use other output buffering functions. Here, I’m forcing some content to be passed back to the caller then sleeping beyond the wait time of 5 seconds.

The results? It waited. So the socket timeout feature in PHP only applies until you receive content. If you receive any content within the socket timeout interval, it will keep the socket open and continue to wait. The timeout actually serves from the opening of the connection to the reception of content, not the entire length of time the socket will remain open.

Thus, I had to find a new route to keeping our Soap calls short. My next attempt was limiting the script execution time via either of these two functions:

set_time_limit(5); // 5 seconds
ini_set("max_execution_time", 5); // 5 seconds

Unfortunately, this didn’t help. First of all, both of these two functions have the exact same effect and use the same underlying PHP functionality. Secondly, they only set limits for internal PHP execution. Any time you have an external data source or blocking system call, this is not calculated in the execution time (at least on Linux; on Windows everything is considered). So any database calls, Soap calls, system calls… These are untimed.

At this point I was at my wits end. I could not figure out a way to limit Soap calls save for building a barebones script to make the Soap call and calling that script with a Curl call.

I ventured into the Soap documentation on the PHP website to see if there was a way I could use the SoapClient class to build the Soap request XML and to parse a Soap response XML into an object, thus allowing me to transport the XML in whatever way I chose. No dice. However, I did discover something interesting while looking at the documentation.

PHP allows you to extend the SoapClient class, I knew that. What I did not know is that you could override certain functions, one of them being __doRequest(). By overriding this function, you can make the request to the remote server however you like.

So I tested this out. And holy crap, it worked. The input to the function is the actual Soap XML, not a Soap object, and the function simply returns the Soap response XML, not an object. It is also passed a few other things, such as the location of the Soap web service. We’re in business.

I built a class extending SoapClient and enabled timeout functionality. When a timeout is used, it actually uses Curl for the call and sets the timeout there. When no timeout is required, it uses the default mechanism to send the request. See part of my class below. It may not be totally robust, but hey, I just needed a timeout. And I couldn’t give you the entire class functionality either. I gotta save something for myself.

class SoapClientTimeout extends SoapClient
{
	private $timeout;
 
	public function __setTimeout($timeout)
	{
		if (!is_int($timeout) && !is_null($timeout))
		{
			throw new Exception("Invalid timeout value");
		}
 
		$this->timeout = $timeout;
	}
 
	public function __doRequest($request, $location, $action, $version, $one_way = FALSE)
	{
		if (!$this->timeout)
		{
			// Call via parent because we require no timeout
			$response = parent::__doRequest($request, $location, $action, $version, $one_way);
		}
		else
		{
			// Call via Curl and use the timeout
			$curl = curl_init($location);
 
			curl_setopt($curl, CURLOPT_VERBOSE, FALSE);
			curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
			curl_setopt($curl, CURLOPT_POST, TRUE);
			curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
			curl_setopt($curl, CURLOPT_HEADER, FALSE);
			curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
			curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
 
			$response = curl_exec($curl);
 
			if (curl_errno($curl))
			{
				throw new Exception(curl_error($curl));
			}
 
			curl_close($curl);
		}
 
		// Return?
		if (!$one_way)
		{
			return ($response);
		}
	}
}

Sphere: Related Content

Categories: Technology, Work Tags: , , ,

The. Man.

April 28th, 2009 No comments

As many of you are likely aware, I have designs on advancing my career past where I’m at now (i.e. this post, here, this one and yet another). I think the next few weeks, perhaps even months, may go a long way to determining if that is possible.

I currently work in a 3-man development team. PHP software development. It’s fun stuff, especially since my team is totally awesome, easy to get along with, hilarious… Etc. It’s me and another developer and our lead developer. Three guys.

We’ve been pretty tight on a lot of our development since the other developer joined the team (I have more seniority than he does). We’re rarely ever bored with nothing to do and occasionally we have so much to do that we’re unsure if we’ll have to start deploying overtime work.

Well… He’s leaving. My coworker got a really nice job offer from somewhere else in town that is giving him the position he covets, a Software Architect position for PHP. I’m happy for him, but at the same time, I’m going to miss having him around here, and am slightly worried about life after he’s gone.

Don’t get me wrong. I know I can handle all of the systems and things he did when he was here. His coding style and object-oriented-ness is at least on par with me, in some aspects above me. But I know I can handle all of it and learn everything he did (see this post I already referenced…).

I’m just worried about being able to keep up. It’s like I said, we were pretty tight since he’s been here, and in two Mondays from now, we’ll open up the day without him as an employee for the first time in over a year and a half.

That is the point where I’ll basically be responsible for all of our code and systems. If you read the previous post I already referenced now three times, you’ll see that there is indeed a division of labor and types of responsibilities between me and my lead, so it’s not like all of a sudden I’ll be a lead. But I’ll be the go-to guy for coding the systems, for administering certain things of the systems.

This means I will finally be the man as far as all of our code goes. I’ll be directly responsible for nearly 100% of all of our deployed code and systems. This was the case when I first started here, before they started up the system that my soon-to-be-former coworker currently works on. When they started that one they handed it off to my coworker-at-the-time and he handed it off to my aforementioned soon-to-be-former coworker. Never have I really been responsible for it (and yes, all of that hyphenation was fun).

So this is my chance to really, really shine. To be the f’ing man around here. It’s an exciting prospect and opportunity, really, to have this much responsibility. I mean, I’ve always had a decent level of responsibility around here, but this takes the cake.

So I’m hoping that this reflects really well on me. I know that eventually we’ll have other developers join the team and I’ll no longer have to handle nearly everything as far as the code goes, but I’m really hoping that the higher-ups see the good job I’ll have done by that point and consider me for positions above my current code monkey status. That would rock.

So we’ll see what the future brings!

Sphere: Related Content

Progress Report

March 19th, 2009 No comments

My skills as a developer have come a long way in the two years I’ve been at my current job. Actually, I’ve been here since March 12th, 2007, so it’s just over 2 years.

When I got here, I thought I knew a lot about PHP. I was kinda wrong. I mean, I was a good programmer, at least I think I still am. But I just wasn’t very awesome at PHP. I’ve grown a lot since then and my style has changed greatly. Let me count the ways.

  1. I’ve started doing object-oriented programming. Well, in this day and age, you need to be able to do this. I only worked with PHP 4 before getting here, since I was on shared hosting and all they offered was 4. They only offered 4 at my previous job, too. So now on PHP 5, I do actual object-oriented programming.
  2. I’ve stopped using private variables all the time. This was early-on in my OOP that I used private variables a lot. Really, you don’t need private vars much.
  3. My commenting is better. I actually comment things now.
  4. My formatting is better. I’ve started using more industry-standard stylings, like uppercase TRUE/FALSE and other things you’ll find a lot in the open-source community. Camel-casing has also made a comeback in my programming.
  5. I’m better at performance-driven applications. I wouldn’t always pay attention to things like running a function in a loop counter. Now I rarely ever make that mistake.
  6. I’m getting better at things like unit tests. I still don’t like writing them, but I’m getting better at them.
  7. I don’t use constants all over the place anymore. I used to use them a lot, but now I try to use things like config files and storing things in a registry, as opposed to a definition that can never be changed.
  8. I’m learning more and more of Zend Framework. It’s a good software suite, too bad I didn’t learn more of it earlier.

Just a smattering of how I’m better. Nothing spectacular. Just happy to say I’ve progressed.

Sphere: Related Content

Twitter Utility

March 3rd, 2009 No comments

So I have Twitter loaded up in a tab often and have found that their website alone doesn’t satisfy the features I’m looking for. I know there are Windows applications that plugin to Twitter and all that, but…

I’ve decided to slake my small thirst for non-work PHP development and I’m going to develop a utility for myself. If it turns out to be good, then I’ll allow other people to use it. :)

Sphere: Related Content

Categories: Development Tags: , , ,

PHP Highlighting

February 3rd, 2009 1 comment

Just wanted to play around with a new plugin I installed here on my blog for code syntax highlighting! Yes, the geek in me comes forth today.

< ?
echo "Hello World!";
?>

Haha. I’m hilarious.

Sphere: Related Content

Categories: Technology Tags: ,