Showing posts with label web. Show all posts
Showing posts with label web. Show all posts

Sunday, August 15, 2010

A public response to Gene Quinn on the "Google removed Oracle" forgery

My quick debunking of Google Briefly Punishes Oracle by Removal from Google Search has been retweeted a lot and even linked from Tech Crunch.
I can't reply on all the different web sites where Gene Quinn, the author, is "sticking to his guns" (I learnt a new English expression today) and say that we are all wrong.
So I'll summed up my thoughts here, with a response to one of his typical comments. The comment is nearly identical to one posted by him on his own article (particularly the bits about typing oracle instead of using a link and the screenshot as a proof), so we can assume it's authentic.
It is Tech Crunch, not me, that has been duped. 
Unfortunately, someone at Tech Crunch knows what Unicode is. You probably don't.
You can believe what you want, but I was not provided a link. I watched someone type “oracle” into Google search and this was what was produced. 
This does not imply anything - I can configure a keyboard to produce homograph cyrillyc characters when I press keys like a and o. Everyone who has ever installed a wrong keyboard driver knows that the characters printed on the keyboard are not electronically hardcoded and depend on a software configuration.
I requested a screen shot. So those, whoever they are (including Tech Crunch) that are claiming this is false are incorrect. Those saying I was sent a link with an intentionally malformed search term are likewise wrong.
This does not imply anything, again. Holy crap, Batman, you are an attorney, do you bring screenshots in court? I can easily make one by simply saving the page and modify the HTML source.
Furthermore, the provided screenshot shows exactly links to pages which contain the fabricated query, like http://dvlprs.com/link/2483939. Those pages are the only shown just because they were the only ones containing the oracle word spelled with 4/6 as Cyrillic characters. By now, the same query will include all the articles which talk about this story.
This is the freezed version of his article in case he decided to take the image down (basically this is a screenshot made by a trusted third party, freezepage.com). And this is the freezed version of his screenshot:
If you try visiting the links, you will be brought to pages containing the fabricated query.
If Tech Crunch has any journalistic standards they would remove this post which offers nothing but speculation passed off as fact. My guess is that if and when Oracle makes this an issue during their litigation Tech Crunch will be printing a retraction. So, you have been warned. I am sticking 100% behind the report because it is true.
This is only FUD. You are expected to publish an amendment to your article, basing on the evidence about your own screenshot linking to a forgered query which explains everything. You may want to know that when you publish links in an image, people can actually following them by typing their URLs in the location bar of browsers.
Next step, you'll treaten me to take down my blog?

Saturday, August 14, 2010

Google never removed Oracle from its index

Some folks have been reporting a strange behavior assumed by Google after the lawsuit filed by Oracle against Android and Google: it supposedly removed oracle.com pages, and all the pages that talk about Oracle, from its search index. Even the wikipedia page on the Delphic oracle.
I initially retweeted the news and explained that it was a trick shortly after.
It would have been a low shot, really. I don't think it's even possible to remove that large set of results on all the datacenters of Google in a short time frame.

What really happened
Someone made up this query:
http://www.google.com/search?q=оrаcІе
Initially the result page was empty (Your search - ... - did not match any documents).  Then people began tweeting and sharing the query and Google started showing up them as the unique results:


So how did they do it?
At first I thought someone used a capital i (I) to substitute the L of Oracle, but Google is smart and would perform a case-insensitive search in this case:
http://www.google.com/search?q=oracIe

Nevertheless, the difference between capital i and lowercase L is not so visible in Google's font.
But, if you try to paste the link or save the page and go over it with hexedit, you'll notice this:
http://www.google.com/search?q=%D0%BEr%D0%B0c%D0%86%D0%B5
This is clearly the sign that someone has inserted non-ASCII characters in the query.
The character table for Unicode/UTF-8 says that we have, in sequence:
CYRILLIC SMALL LETTER O
LATIN SMALL LETTER R
CYRILLIC SMALL LETTER A
LATIN SMALL LETTER C
CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I 
CYRILLIC SMALL LETTER IE
This combination of characters is very unlikely to be found in actual documents. In fact, at first it did not produce results. Furthermore, in Google's font of choice, Arial, the difference between these letters and their latin counterparts (if there is any) is again not clear to the naked eye. It makes sense to reuse glyphs that are actually the same in ordinary printed text.
And finally, the forgery replaces the majority of the latin letters, because replacing only one or two would lead to a Did you mean: oracle notice.

Mystery solved
So UTF-8 struck again, and some of us were fooled by a ingenious, well-forgered Google query. Technically this is called an homograph attack.
The potential of UTF-8 as a dangerous mean of fooling users is great - imagine if non-latin URLs will become a reality. Fortunately, the ICANN and major browsers have been working on a solution, but we as web developers should be aware of the problem too.

Tuesday, April 27, 2010

Transparent remoting is a fable

Transparent remoting is the use of the Proxy pattern to create remote proxies, that conforms to the same interface of a remote object but instead of executing its methods locally it marshals (serializes) the parameters, send it over the network, get the marshalled result and returns it to the client code.
The idea behind this pattern's implementations is using a remote object, discovered with some kind of infrastructure service, as it were in the same address space of the current process. The most famous implementation is probably Java Remote Method Invocation (RMI).

This is nice!
However, the famous paper A Note on Distributed Computing outlines the inherent issues of treating remote and local objects with the same interface and contract:
  • latency: obviously, it takes more time (some orders of magnitude) to perform remote calls in relation to local calls.
  • memory access: it is performed via pointers and handlers on local machines, while it is more complex in remote invocations. More or less solved in Java RMI via stubs and skeletons.
  • partial failure: remote objects can suffer different failures which are not included in the original interface. For instance, they can raise RemoteExceptions which you must deal with a try/catch block. Or they can let you wait a method's return value forever (actually until a timeout is reached.)
  • concurrency: calls from different nodes can happen at the same time, and there is no single point for managing shared resources like a common operating system.
The first two are problems we can live with, while the third and the fourth have no conceptual solution. In sum, remote proxies are a leaky abstraction, and it is difficult not to notice that an object is remote.

Isn't trasparency over the network a simplification?
It is more an old myth, and often too much of a simplification. Single-machine deployment for web applications exist, and they can be transformed into multiple-machine ones. How do they tackle the problem?
These infrastructures do the job backwards. They assume a service like a database is going to be remote, and if it is local, well nothing changes, you can just stick a localhost or 127.0.0.1 in the configuration. Sockets are used for communication between Unix components from the 1970s, and they are not a leaky abstraction. Even RMI forces you to throw RemoteExceptions from a local object (and this is the first failure of transparent remoting).

Isn't RMI useful?
Of course, in the correct use cases RMI can be handy. For example if you are in a LAN, and are in an hurry to separate an application server from your web servers, you will certainly use RMI to access beans on the former. As long as it is not used transparently, it is a great technology.

So should we stop doing remoting with objects?
No. Even JavaScript nowadays does remoting in Ajax applications, but it has a different model, which is asynchronous. Of course some Java infrastrucure is by nature asynchronous, Java frameworks are introducing an asynchronous model for calling remote objects (R-OSGi).
IRemoteService remoteService = (IRemoteService) reference.getProperty(REMOTE);
// This futureExec returns immediately
IFuture future = RemoteServiceHelper.futureExec(remoteService, "hello", new Object[] { CONSUMER_NAME });
// ...do other computation here...
// This method blocks until a return 
future.get();
System.out.println("Called future.get() successfully");
You can wrap future.get() in a separate thread and continue with your life. This is almost like doing an Ajax call: your browser does not freeze while the request is being completed. Asynchronous method calls are an interesting innovation (not really an innovation since they are older than dirt) over transparent invocations, and open up new models for distributed computing.

Wednesday, February 03, 2010

Where is business logic?

Have you ever heard of Multitier architecture? If not, you have probably encountered it without knowing its name while working on web applications.
In a multitier architecture, an application is divided in different horizontal layers, each addressing a different concern. Every layer builds on the one that lies directly under it to perform its work, thus decoupling for example html presentation (upper layer) from sql queries (lower layer).
The number of layers is flexible and there is a high number of variants for a multitier architecture, but the simplest model many web applications fall in is composed of three layers:
  • user interface: generates html, handles user input and displays errors.
  • Domain Model: objects and classes that represent concepts, such as Post, Thread, Forum, User, Message and so on.
  • Infrastructure: usually data access code to a database and, by extension, the Sql schema itself where the relational model is used. External services also qualify as infrastructure.
Thus there are three major approaches to development, which differ in the layer of the application that contains the greater quantity of business logic. Which User can close a particular Thread and in what order the Messages for a particular User are listed? In which Forum a User can add a Post?
The answers to these questions ideally reside in one of the fundamental layers as specifications require (though sometimes they are scattered trough the layers, which is a very effective way to complicate a design.)

Smart Ui
As the name says, this style keeps the logic in the user interface. A Smart Ui example is a folder full of php scripts that move data back and forth from a MySql database.
During maintenance, usually the replication of rules and code in different scripts increase, rendering difficult to change and expand the application; this style is appropriate only for small projects which only shuffle data from tables to html pages.

Smart database
A style primarily taught in database classes, which result in a very accurate schema, full of constraints, triggers and stored procedures to maintain data integrity.
Note that if you want to implement this approach, you probably need an expensive database like Oracle because open source databases do not support all the logic you need. Moreover, Sql is not a programming language, you can stretch Ddl with proprietary extensions and set up many rules but you will be replicating them in the front-end (if there is one at least) for error handling and localization.

Rich Domain Model
The most powerful approach is implementing logic in the domain model layer, which is the type of model that should be able to best represent the real world.
It follows that in such an approach the Ui delegates nearly everything to the domain layer, or it is even automatically generated (Naked Objects). Technology is available for the database to be generated automatically once a mapping from objects to tables is defined (Orms like Hibernate and Doctrine 2). The dependencies are inverted as all other layers mirror the domain model.
The advantages of a rich domain model are multiple:
  • testing is simple because infrastructure and Ui do not get in the way; no need to run databases to test business logic or to fill forms with a bot or Selenium.
  • no duplication of logic is permitted, because different views of the user interface refer to the same methods in the domain model.
  • the model of the application is the model presented to the user; there is no translation between concepts and no need for him to learn a data model along with a presentational one. Often a Presentation Model is needed because the underlying Domain Model is anemic.
Essentially with the tools available today for managing generic layers you can achieve everything by manipulating objects directly in memory and storing the result in the database by pushing a big Save button.

Monday, September 14, 2009

Pagination is dead

Pagination is the feature for displaying a long list of entities in a web application: a division of them per page and a list of link to the various pages. Today there are better solutions to this classical problem, and some of them were always available even in the first days of the web.

The typical scenario solved by pagination is to allow the search of a particular entity from a list, by displaying it a chunk at the time. Particularly in web applications, where page size is limited by bandwidth, the maximum amount of items contained in a page is fixed in less than an hundred:
The problem with pagination is how often do you look to page 2?
I google many times a day, so many that I now use the search bar of firefox instead of loading the homepage and entering the query in the input field. I usually found the first or the second result to be the most reliable resource for the query I entered since Google ranking is legendary: it's Google that decides how popular an article on this website will be and the only thing that competes in popularity with Google ranking is social network one.
Thus, I never went to the 2nd page of a Google search result. I bet you neither have done the same more than once or twice this month, and probably refining your search terms would have put the link you were looking for in the first position of the first page. Since the first link is almost always what you will be clicking some seconds later, Google main page even feature the I'm Feeling Lucky button which does this work for you.
In my opinion, Google pagination is rather useless.

In the early years of the web, pagination was the killer feature: LIMIT clauses for databases were everywhere and calculation of its argument were spread all over an application. This blog, hosted on the Blogger platform, also implements pagination: but do you prefer to scan my archives five posts at the time or to use the search box on the right?
Although all the content is available in a list of pages, a blog is not a book and it is not sequential: articles are often found by visiting a particular label or by a Google result. Honestly I sometimes look to the page 2 or 3 of a blog to form an idea on what content is posted there and decide whether to subscribe to the atom feed, but I think the author would rather have me look to a search on a tag, to a collection of popular posts or to its about page.

What about different kind of lists to paginate? Wikipedia lists are often very long: sometimes pagination is not adopted, like in the link, and the result is a unfocused and difficult to navigate page. But if you refuse to paginate there are other ways to manage this big pack of data:
  • showing results on demand a la Dzone: thanks to ajax requests, when an user reaches the end of the list or is at the last items, another chunk is lazy loaded to fill the empty space between the list and the end of the page.
  • better search system: as we have discussed earlier, Google does not need pagination since it is the best search system and you'll find your desired result in the first 10 links. Provide a mean to search a big list instead of spitting it all out, leaving the burden on the end-user.
  • real time filtering: a dojo grid presents a pagination similar to the Dzone one, but different filters can be attached to modify the query. The result is similar to google suggestion while typing in the text field, as when you add characters to your search string the filtering is performed instantly.
These are only examples of what can be done if you force yourself to not paginate. The question which I repeat here is always the same:
Who will have the patience to look at page 2?
If you keep in mind this problem, finding another user interface to substitute pagination will be at the top of your todo list.

The scroll at the top of the page shows you a continuos source of pages that reminds of pagination sliders where you can go only to the next and previous page. It was very inefficient, but ancient monks did not have Google search capabilities...

Wednesday, September 02, 2009

Deployment of php applications

Deployment is the process of taking live a codebase: make a web application work by transporting it to the production server, configuring it in the local environment and start the needed daemons. Here is a checklist for deploying php applications, which have the advantage of not requiring compilation.

Transporting the codebase
I used mainly two types of file transfer to get a working copy of an application:
  • ftp: it is the most proven technique and was the right choice for uploading a large amount of data. It is slowly becoming obsolete for deployment purposes but almost every hosting provider offers an ftp service.
  • ssh and subversion: where available, a remote shell with a working copy of the codebase under version control is a powerful choice for rapid updates, since it keep track of local "hot" changes and it transmits only modified and new files over the network.
It is considered good practice to checkout in an auxiliary folder and to work on it until the application is ready. A symbolic link is then established to this new folder for simple rollback is something goes wrong (and it will).

Setting up the environment
You should never forget to check source files and environment properties to make sure the application is runnable and it can act on the right data.
  • writable (aka public) folders: some folders have to be writable from the php process because files will be kept in them after uploading or elaboration. Ftp transfer normally does not mantain chmod permissions, so you may have to tweak it manually.
  • file permissions: the same configuration applies to writable files, like sqlite databases or similar.
  • database schema: every version or release of an application which uses a relational database will work along with a particular version of the schema, the definition of tables and their columns. A migration script should be prepared to upgrade the table from the previous structure. If it's the first deployment, the database must be created ex-novo.
  • other setup: any product will probably have a configuration script or web page to run, or a config file to compile. For example blogs and cms need database credentials that must be entered in a config.php file which will be included in every http request.
Starting the daemons
About the php case, the database and web servers are always running, being them on a shared or virtualized server. Php applications have a shared nothing architecture, so once they are configured the web application should run smoothly: this is a very different workflow from Java one, where you have to recompile and/or a packing a new jar. It theory, you can work by manually modifying scripts and uploading to a web server, but it is not a very good practice.
In some cases, a restart of webserver is needed, for instance if using aggressive apc options which cache in memory the content of php scripts. Otherwise, php scripts will be interpreted as needed by user requests.

Be sure to double check your assumptions; going live is a delicate procedure but is the key to show the world your beautiful product.

Monday, August 10, 2009

How to not waste time surfing blogs: introduction to feeds

Have you ever returned to a blog every day or hour to see if the author has written some new, great post? What if the blog you follow are more than an hundred? When too much components are involved, the Publish/Subscribe pattern comes helping, to decouple the subscribers (readers) from following every publisher (blogs) and conserve some productivity instead of surfing an hundred blogs to seek updates.

Publishing
When a website has to syndicate a list of items which is frequently updated, it can place an xml document conforming to certain standards where these items are kept (usually only the last ones published, and with a shortened description in place of the content to keep the document lean). The typical formats used are Atom and Rss, and since the main feed aggregators supports both they are somewhat equivalent.
The list of items can be everything: Invisible to the eye, this blog, publishes a feed for the new posts and for the comments; Wikipedia publishes the list of changes to a page; Twitter the list of an user updates.
Feeds are normally generated by a server-side script, in my case the same that manages blog posts; it can derive feed fields (title, text, url) from the posts table in the database. When a feed is in place, the tedious process of open the main page to check if new articles have been published is standardized and can be automatically done by a program or a web application for us.
The last step is to take advantage of autodiscovery: placing a special link tag in the head section of html documents can link to a xml feed which will be displayed by browsers as available for subscribing. In Firefox, for instance, a small icon appears in the location bar where a feed exists as an alternate version of a page content.

Subscribing
On the other side, feed aggregators manage a list of feeds you subscribed to. When you discover a feed, you can put the url in a program or web application that will check periodically, every few hours, the feed for you.
Every time the aggregator gathers data from feeds, it lists the new items that you have not already read and organizes them as you like. When you want to check your list of 100 preferred blogs for new content, the only action needed on your side is to open Google Reader and see the list of new articles. Every post has a globally unique url which act as a primary key.
I prefer web application for aggregating data since they mantain the list of current unread items in every machine where I'm viewing them. Ideally, they can also do only one ping for every feed even if thousands of users are subscribed: they are the Blackboard of this pattern.
In a real publish/subscribe system the websites should notify the aggregator of new items, but the http technology is limited and the inverse process happens to emulate a push style. However, some extension to this mechanism is in development.

Wrapping and mashups
Once a standardized way to let content flow such as xml feeds has been developed, new ideas come up and xml is a pillar of web 2.0:
  • FeedBurner is a wrapping service that envelopes a feed giving you a nice, short url: then you can link in your pages the FeedBurner version and gain automatic statistics and optional reformatting, and also embellishment of the syndicated data when viewed in-browser (with links and buttons to pass the feed to the most famous web based aggregators).
  • A mashup is an application that combines external sources of content and provides a unique view of them. For instance if you are a fan of php, you can subscribe to a feed of a php mashup which publishes the best php articles it finds scanning thousands of feeds around the web, filtering out the bad choices.
Now you have a general view of how xml feeds works. I hope you will join the web feed of this blog if you want to remain informed of brand new articles.
And if you do not have a feed aggregator yet, check out Google Reader.

Saturday, July 04, 2009

Using Apache Bench to monitorate performance

What about an application that feels 'faster' than yours? Or pages that seems to load slowly than others? We'll use ab command line tool to measure load times of your pages in scientific way. Example based on this Ossigeno installation.
Installation
Apache Bench is a command line tool, open source like Apache Httpd Server, that performs simultaneous and repetute requests to an url to simulate traffic and outputs a statistical analysis of performance.
On Ubuntu, it's available by:
$ sudo apt-get install apache2-utils
and then
$ ab ....
to execute Apache Bench.

Usage
Let's see it in action:
$ ab http://ossigeno.sourceforge.net/blog
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking ossigeno.sourceforge.net (be patient).....done


Server Software: nginx/0.6.31
Server Hostname: ossigeno.sourceforge.net
Server Port: 80

Document Path: /blog
Document Length: 334 bytes

Concurrency Level: 1
Time taken for tests: 0.433 seconds
Complete requests: 1
Failed requests: 0
Write errors: 0
Non-2xx responses: 1
Total transferred: 632 bytes
HTML transferred: 334 bytes
Requests per second: 2.31 [#/sec] (mean)
Time per request: 432.576 [ms] (mean)
Time per request: 432.576 [ms] (mean, across all concurrent requests)
Transfer rate: 1.43 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 162 162 0.0 162 162
Processing: 271 271 0.0 271 271
Waiting: 271 271 0.0 271 271
Total: 433 433 0.0 433 433


That is a lot of info, and some noise is present. Ab has made one request to sourceforge.net and outputs time elapsed and other statistical info like mean and median. However, the most important parameter is Request per second, that represents how much different pages the httpd server can serve in 1s. Let's cut out unnecessary statistical data:

$ ab http://ossigeno.sourceforge.net/blog | grep Request
Requests per second: 3.02 [#/sec] (mean)

Ok, it seems that this server of sf.net can send out three pages every second. This is only one server: it has many and when we type ossigeno.sourceforge.net in our browser we are redirected through a load balancer to one of them.
Well, one request is not statistically significative: it can be noticeably faster than others because our request was sent in a particular idle instant. Or it can be slowed down because some cached elements were refreshed while serving our request. So let's do what a statistic will do: increase the sample size.

$ ab -n 100 http://ossigeno.sourceforge.net/blog | grep Request
Requests per second: 2.70 [#/sec] (mean)

Ab makes one hundred request in a row, and it calculates the mean of loading times. With this loading time, we see that this server can serve out 2 pages and a half every second. That's pretty fast.
What if simultaneous users request pages at the same time? A webserver is designed to have multiple process that works on different http requests. So, let's see if sourceforge.net is scalable:

$ ab -n 100 -c 5 http://ossigeno.sourceforge.net/blog | grep Request
Requests per second: 12.82 [#/sec] (mean)

Ab makes one hundred request, five at time, opening simultaneously five connection to sourceforge.net; we see that request per second is increased to ~13. What does it mean?
Let's put in this terms: if we request a page, it is sent to us in ~0.3s. If we request two pages at the same time, they are sent to us still in ~ 0.3s. So the server it's not a bottleneck at this level of concurrency, because it can handle 5 simultaneous request without slowing down them. If we increase concurrency level:

$ ab -n 100 -c 20 http://ossigeno.sourceforge.net/blog | grep Time
Time taken for tests: 2.082 seconds
Time per request: 416.397 [ms] (mean)
Time per request: 20.820 [ms] (mean, across all concurrent requests)
Connection Times (ms)

the time for serving one page increases to only 0.4s, that is a kick-ass performance.

Conclusion
Profiling is the essence of optimization: you have to see where is the bottleneck to improve your application.
Apache Bench is a useful tool as it monitor loading times of webpages, going beyond human sensations of "speed" and provides statistics calculated on a sample of request that you can choose. You can activate and disactivate some modules of server, like mod_deflate for Apache or apc at Php level or Zend_Cache in your application, and see with ab what makes your server works faster, basing on collected data.

Php deployment with Subversion

Subversion, svn for friends, is a source control system, which stores all your source files and their history in a centralized place. How to use Subversion for deployment of websites?

Have you ever had the pain of deploying some megabytes of php source files with ftp? It takes some time, and using library and/or frameworks in you application the total size of files to be transferred is high. Moreover, also the number of single files is huge and this fact will slow down the process while your ftp client walks in and out of thousands of directories.
What if some configuration files are modified? You have to manually search the folders to replace and upload only the "engine" files, while avoiding to overwrite some config.inc.php which database credential are stored in. This is a daunting task to do with ftp.
Take away the pain with Subversion!

Prerequisites
Using a subversion client to deploy your web application requires, obviously, that the php files are stored in an svn repository. On the other hand, using a svn repository gives you only benefits over plain storing of php files in the filesystem, that goes over the scope of this article. Since Ossigeno is open source, I use SourceForge svn repository, that comes for free. If you develop a commercial application, you can eaily set up a svn repository on your machine. I use an old laptop with Ubuntu Server installed to store private modules sources (modules built for contractors), with port forwarding from the router to the laptop and a dyndns account to provide.
To run svn in the document root of the webserver, you'll need to have ssh access to the machine, or, alternatively, have physical access. For instance, this blog runs on SourceForge webserver, and SourceForge gives shell access to registered users. Tipically 8€/year shared hosts does not offer this type of service, however.
Finally, the svn client has to be installed on the webserver. If you have shell access, it's very likely that also svn is present. To find out, simply run:
$ svn --version
on the shell and see what happens.
Now that we know we have the tools for the job, let's install an Ossigeno copy from svn repository.

Initial checkout
Supposing, we are in the folder where we want to install (a document root subfolder /var/www/blog or the document root itself /var/www), we simply run:
$ svn checkout https://ossigeno.svn.sourceforge.net/svnroot/ossigeno/tags/3.0_beta6/core/ .
The SourceForge path has to be substituted with your server path. An hostname should be used, while an ip will not work correctly if it is dinamic (that is probably the case if you don't have an hostname). Subversion stores in its .svn hidden folders the hostname used for the initial checkout, so you don't have to retype a long url everytime you update.
Now that you have a working copy, you can proceed to install the application as it was extracted from a tarball or from a zip package.
Some school of thought uses the svn export command to obtain a copy of the code, but a checkout is more useful for what we're doing next.

Common operations
You had found a typo in a source file, and you corrected it on the webserver. Since this is a working copy and not an exported one, you can simply do:
$ svn commit -m "fixed a typo" folder/script.php
and the diff with the original file will be sent to the repository, sending upstream the simple patch you have created. Depending on your repository setup, a password or a rsa key will be requested by the svn client to proceed with commit.
Now you want to update you application to a new version: this version (of Ossigeno in the example) is tagged 3.0_beta7. This is work for subversion.
$ svn switch https://ossigeno.svn.sourceforge.net/svnroot/ossigeno/tags/3.0_beta7/core/ .
The repository will calculate the diff between 3.0_beta6 and 3.0_beta7 and will send to the client a temporary patch that will be applied to the working copy on the server where you execute the command. Please note that this operations are possible only because we choose to use checkout instead of export. The checkout command duplicates the original files in .svn folders, and thus double the space occupied; but it is very fast on updates and commits because only the file deltas are sent over the network.
So you can switch over the main branch of Ossigeno to have the bleeding edge version:
$ svn switch https://ossigeno.svn.sourceforge.net/svnroot/ossigeno/trunk/core/ .
and every two days run
$ svn update
to obtain the last features.
The last two steps are not recommended as trunk randomly breaks the working copy, being a in-development version.

Issues
You have edited script.php, but not commit this to the repository since it is a local hack that must not spread to other copies of the application. What will happen when you run switch or update?
The answer is multiple. If the file is not modified in the repository, your local copy will be mantained as-is. If the remote file is changed, svn will try to merge the files in a new version and only if the changes overlap, you will be prompted for a manual edit that will resolve the conflict. In Ossigeno example, configuration files are stored in a folder with svn:ignore property set with a filename corresponding to the host, so a file is added for the local configuration in application/config directory and ignored from subversion in commits and updates.
I encountered another issues while installing Ossigeno on this server. In the static/ folder some public directories are kept; Ossigeno puts cached html in static/cache/ and image previews in static/preview/, thus the webserver/php process needs writing permissions on the folders. However, on SourceForge the document root htdocs/ is readonly (from the webserver), and writable directories has to be created in persistent/ and pointed by a simbolic lynk in the htdocs.
So what's the problem? Those dirs were in repository, so I cannot remove them and place some simbolyc links. I had to remove the public dirs in repository, saving static/ as an empty folder with svn:ignore property set to '*'. Then I set up a phing task to recreate them and to setting the writing permissions, leaving the option to the user to create them manually, with phing task or with the installation process, or eventually to put some symlinks in static/.

Conclusion
This points out a general rule to use with subversion deployment: do not import in repository what will change on the production box. Do not import configuration files, because if you do at the next svn commit (that defaults to the current folder) you will sent to your repository the database credentials of the website; do not import dirs that can be substituted by symlinks, because if you removes those folders you will break the working copy. Do not import temporary files. You can setup svn:ignore property on folders to have this files not listed by svn status (see the best Subversion documentation, its book).
Have a nice day using the power of Subversion not only for development but also for deployment!

Featured post

A map metaphor for architectural diagrams

It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

Popular posts