Friday, 26 March 2010

Fixing Michael Galpin's Comet Tutorial

I recently stumbled across the following tutorial on Comet:

Build Comet applications using Scala, Lift, and jQuery
http://www.ibm.com/developerworks/ajax/tutorials/wa-aj-comet/index.html

I was interested in this tutorial as comet is an alternative architecture to Ajax. In Ajax the browser makes calls (polls) to the web server in the background and then updates the users web page. This issue with this approach is that there is a delay between a change and the polling call. Also when you have a large number of users there will be a lot of polling calls hitting the web server that will not update the users web page (as there was no change).

Comet takes an alternative approach where it keeps a connection open to the user's browser and uses this to push data to the use. The benefit of this approach is that it essentially uses the Observer Pattern an only has web traffic when an update has been made which reduces load on the web server and is more scalable.

a potential replacement for Comet is Web Sockets in HTML 5 but this isn't supported by all browsers at present.

Anyway, when I tried building the tutorial I found that Michael had used a snapshot build to get new features but as this is a snapshot it is removed later from the Maven repositories giving this error:

[INFO] Failed to resolve artifact.

Missing:
----------
1) net.liftweb:lift-core:jar:0.10-SNAPSHOT


This is easily fixed by moving to the released version by changing pom.xml from:

net.liftweb
lift-core
0.10-SNAPSHOT


to the release version:

net.liftweb
lift-core
0.10


But unfortunately there were changes between the snapshot and the release which threw the following errors:

[INFO] Compiling 7 source files to C:\dev\scala\lift\broken_auctionNet\target\cl
asses at 1269595709118
[ERROR] C:\dev\scala\lift\broken_auctionNet\src\main\scala\bootstrap\liftweb\Boo
t.scala:44: error: value appendEarly is not a member of object net.liftweb.http.
LiftRules
[INFO] LiftRules.appendEarly(makeUtf8)
[INFO] ^
[ERROR] C:\dev\scala\lift\broken_auctionNet\src\main\scala\bootstrap\liftweb\Boo
t.scala:66: error: not found: type Can
[INFO] private def createOne: Can[Connection] = try {
[INFO] ^
[ERROR] C:\dev\scala\lift\broken_auctionNet\src\main\scala\bootstrap\liftweb\Boo
t.scala:87: error: not found: type Can
[INFO] def newConnection(name: ConnectionIdentifier): Can[Connection] =
[INFO] ^
[ERROR] C:\dev\scala\lift\broken_auctionNet\src\main\scala\org\developerworks\co
met\AuctionActor.scala:18: error: type mismatch;
[INFO] found : java.lang.String("auction")
[INFO] required: net.liftweb.util.Box[String]
[INFO] def defaultPrefix = "auction"
[INFO] ^
[ERROR] four errors found

The Can errors are fixed by replacing Can with Box in the two places in boot.scala

To fix the final error replace:
def defaultPrefix = "auction"

by boxing it Full and make it an override as follows:
override def defaultPrefix = Full("auction")

This fixes the errors but when you compile you get the following error in boot.scala:

[INFO] Compiling 7 source files to C:\dev\scala\lift\broken_auctionNet\target\cl
asses at 1269597516624
[ERROR] C:\dev\scala\lift\broken_auctionNet\src\main\scala\bootstrap\liftweb\Boo
t.scala:44: error: value appendEarly is not a member of object net.liftweb.http.
LiftRules
[INFO] LiftRules.appendEarly(makeUtf8)
[INFO] ^
[ERROR] one error found
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR

This is fixed by changing the line from:
LiftRules.appendEarly(makeUtf8)

to:
LiftRules.early.append(makeUtf8)

The code now compiles but when you start it using mvn jetty:run you get the following

2010-03-26 10:06:39.757:WARN::failed org.mortbay.jetty.plugin.Jetty6PluginWebApp
Context@33c78b{/,C:\dev\scala\lift\broken_auctionNet\src\main\webapp}: java.lang
.VerifyError: (class: net/liftweb/util/EmptyBox, method: open_$bang signature: (
)Ljava/lang/Object;) Can only throw Throwable objects
2010-03-26 10:06:39.757:WARN::failed ContextHandlerCollection@171bc3f: java.lang
.VerifyError: (class: net/liftweb/util/EmptyBox, method: open_$bang signature: (
)Ljava/lang/Object;) Can only throw Throwable objects
2010-03-26 10:06:39.757:WARN::failed HandlerCollection@1fddb33: java.lang.Verify
Error: (class: net/liftweb/util/EmptyBox, method: open_$bang signature: ()Ljava/
lang/Object;) Can only throw Throwable objects
2010-03-26 10:06:39.757:WARN::Error starting handlers
java.lang.VerifyError: (class: net/liftweb/util/EmptyBox, method: open_$bang sig
nature: ()Ljava/lang/Object;) Can only throw Throwable objects
at net.liftweb.http.LiftRules$.(LiftRules.scala:171)

This is resolved by increasing the Scala version to 2.7.3 from:

2.7.2

to:

2.7.3

Wednesday, 17 February 2010

Moving Exception Messages back onto the normal AQ queue

Just wrote some PL/SQL to restore messages on the exception queue back onto the normal queue.


DECLARE
dequeue_options dbms_aq.dequeue_options_t;
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
message_handle RAW(32);
message SYS.AQ$_JMS_TEXT_MESSAGE;

deq_qname varchar2(50);
enq_qname varchar2(50);

ex_no_messages exception;
ex_dequeue exception;
pragma exception_init (ex_no_messages, -25263);
pragma exception_init (ex_dequeue, -25228);
msg_count number;
BEGIN
deq_qname := 'SCOTT.AQ$_TBL_DATAFEED_REQ_E';
enq_qname := 'SCOTT.DATAFEED_REQ';

dequeue_options.wait := DBMS_AQ.NO_WAIT;
dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
dequeue_options.dequeue_mode := dbms_aq.remove_nodata;

msg_count := 0;

-- Enabling the exception queue for dequeue
dbms_aqadm.start_queue(deq_qname, false, true);

LOOP --Looping to find and remove the message from exception queue
dbms_aq.dequeue(queue_name => deq_qname,
dequeue_options => dequeue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);

dbms_aq.enqueue(queue_name => enq_qname,
enqueue_options => enqueue_options,
message_properties => message_properties,
payload =>message,
msgid => message_handle);

dequeue_options.navigation := DBMS_AQ.NEXT_MESSAGE;

msg_count := msg_count + 1;

DBMS_OUTPUT.PUT_LINE ('Processed ' || msg_count || ' messages');

dequeue_options.navigation := DBMS_AQ.NEXT_MESSAGE;
END LOOP;

EXCEPTION -- exception handling
WHEN ex_no_messages THEN
DBMS_OUTPUT.PUT_LINE ('No of Messages Moved: '||msg_count);
COMMIT;
WHEN ex_dequeue THEN
DBMS_OUTPUT.PUT_LINE ('No of Messages Moved: '||msg_count);
COMMIT;
END;
/

Extracting data from a JMS Text message

Some useful SQL to extract data from a JMS Text message

SELECT SUBSTR(q.user_data.text_lob, INSTR(q.user_data.text_lob,'') + 20,7) "Special Reference",
SUBSTR(q.user_data.text_lob,
INSTR(q.user_data.text_lob,'') + 19,
(INSTR(q.user_data.text_lob,'
')
- INSTR(q.user_data.text_lob,'') - 19)
) "Contact",
SUBSTR(q.user_data.text_lob,
INSTR(q.user_data.text_lob,'') + 5,
(INSTR(q.user_data.text_lob,'
')
- INSTR(q.user_data.text_lob,'') - 5)
) "REF"
,q.MSGID, q.CORRID, q.ENQ_TIME, q.DEQ_TIME, q.RETRY_COUNT,
CASE WHEN q.Q_NAME = 'AQ$_TBL_XMLMSG_E' THEN 'FAIL' ELSE 'PASS' END as "successful",
q.Q_NAME, length(q.user_data.text_lob) as "MSG Size", q.user_data.text_lob, q.user_data.text_vc
FROM MSGUSER.TBL_XMLMSG q
WHERE q.ENQ_TIME > to_date('12-02-2010 00:00:00', 'dd-mm-yyyy hh24-mi-ss')
AND q.Q_NAME = 'AQ$_TBL_XMLMSG_E'
AND INSTR(q.user_data.text_lob,'Tester') = 0 -- Exclude Test records
ORDER BY q.DEQ_TIME desc, q.ENQ_TIME

Wednesday, 10 February 2010

Scala and Lift Maven Architypes

Maven Architype command line instructions to be used with Maven 2 to create new projects

# Basic Scala maven type
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create -DarchetypeGroupId=org.scala-tools.archetypes -DarchetypeArtifactId=scala-archetype-simple -DarchetypeVersion=1.1 -DremoteRepositories=http://scala-tools.org/repo-releases -DgroupId=your.proj.gid -DartifactId=your-proj-id

# Lift type for LIFT projects
mvn archetype:generate -U -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-blank -DarchetypeVersion=1.0 -DremoteRepositories=http://scala-tools.org/repo-releases -DgroupId=play -DartifactId=play -Dversion=1.0-SNAPSHOT

Wednesday, 27 January 2010

Reading Oracle AQ JMS Text XML

Placeholder link to a great and very useful article on Oracle AQ JMS

Wednesday, 20 January 2010

Listing today's files in a directory without using find

Had an issue today where I needed to get the today's log files from a Unix directory but couldn't use find. Normally I could use the time function in find to do this as follows where . is the directory to search from (. is the current directory):
find . -mtime +0
However the only way I could get the date for the files was by using ls -al and then removing all the extra data to leave just the filename.

The following script takes an argument of the directory you want to list all the files with the current date:

#!/bin/sh
die () {
echo >&2 "$@"
exit 1
}

[ "$#" -eq 1 ] || die "target directory argument required, $# provided"

target=$1
myvar=`date "+%h %d"`

for file in `ls -al $target | grep "$myvar" | sed 's/[-drwx]* *[0-9] *[a-zA-Z0-9]* *[a-zA-Z0-9]* *[0-9]* *[a-zA-Z]* [0-9]* *[0-9]*:[0-9]* *\.*//'`; do
echo $file
done


Monday, 2 November 2009

Testing my posterous account

I this message appears in twitter and on my blog then posterous has processed my email and put it both on my blog and on twitter

this is a test

Posted via email from Paul's posterous