Epiphanic Networks' Wikka : JPoSLookups

Home :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register

Querying the back end


Last edited by KogAdmin:
journaling
Tue, 29 Aug 2006 01:44 PDT [diff]

TODO: clean and reconcile me when done drafting
 

Lookups


Right now products and users are being looked up locally. I'll build a fake RMI module, and then later hook into the actual products DB.

Products can only be constructed with Product.lookupProduct, which takes a String of a UPC. Products generally contain a price, UPC and description but will eventually contain stats like how many are in stock (which will mean more frequent cache misses and more lookups).

Users are pretty static - they'll rarely be deleted, and lookups should be infrequent. Users currently have a UID, password (managers) and a managerial status flag.

Orders - you can lookup old orders (eventually), which are basically orders flagged complete. These can be cached too, but will most likely be infrequently looked up, and are quite volitile. Further, the status flag will eventually be upgraded to include other information.

Caching


The cache model will be rather simple: every once in a while the PoS Agent will check the update queues on the server for updates indicating that any of the three caches are tainted. You'll get a specific reference and sync the cache. Lookups will work as in a Von Neumann system - it'll search the cache space first, and hopefully hit. If it faults a lookup will be called via RMI. These shouldn't be too heavy, but it's a good idea to try and cache as much as possible.

Users are highly static, products are mostly static (until you get into volitile information, such as stock levels... you might want to use stock level grouping instead, more below) and orders may, or may not be static.

I'm not sure how the update queue(s) will work right now because I haven't begun researching how to build the servlet, and then the RMI on top of that. I'm hoping to just spin off a thread in the PoS Agent and have it ask the server every x minutes for taints. All caches will have standard methods: cache, destroy item, item tainted, lookup. It's also conceivable that you want to spin off a thread that does cache reclaiming every x seconds, or even use priority queues and lifetimes for individual datum (see below).

Stock levels and caching: you probably won't need stock level information unless you're doing a lookup - so generally stock information need not be cached. However, for a quick turnover store you might wish to know this, and it might be wise to create groupings of stock to minimize taints to the cache (otherwise you'll end up doing a lookup almost every query). You'd end up with something like: plenty in stock, mid stock level, getting low, reorder, out of stock. This way when it crosses a threshold the update queue will trigger and tell the PoS terminal that a new threshold has been reached.

Update
I've implemented the caches as a factory pattern (WikiPedia entry on pattern), so you grab a cache factory and ask it for a cache of users, products or orders. Right now it's implemented as a singleton, but part of the beauty of a factory is such that it's easily modifiable - it's conceivable that you might need multiple cache stores, partitioning for different reasons. It's also nice to be able to tweak the cache such that it can always lookup, that it can use a pqueue instead of a hashtable or any number of mutations.

Currently the RegisterAgent class contains caches and lookups are made against the agent itself. You could consider the register agent as the state of the register itself (see my comments on semi-autonomous negotiations and curvy clients). All caches will be purged upon shutdown (register close, app close) - there should be no writes to the backing store.

UPDATE: RMI goodness from OSCon 2006
 

RMI

It seems that after talking to folks at the BOF (David E Jones) last night, all I need to do to get my RMI on is the following:
1 - Create service definitions. I'll start with the already created one to check a price, and try that one
2 - Grab the RMI libs from the distro and compile against it
3 - call the method remotely and execute the service giving it call(method, valuemap) and get back a valuemap.

Authentication will still probably be a problem, we'll see. I'd love to see documentation of this somewhere - David said it exists somewhere, and sometime when it's not 0229 and I don't have to be up in a few hours, I'll indeed go and look... I promise

UPDATE
It appears that the Authentication can be done by passing in a map of IN values, so that shouldn't be too bad. It also looks like I can leverage the existing system, and possibly create new roles that only exist for the PoS. David E. Jones pointed me to ExampleRemoteClient.java in framework\service\src\org\ofbiz\service\rmi which has some examples, as well as JARs and property files (not really sure why... must be something at runtime. I'll have to check later). Thankfully I'm using Ant for builds, so throwing in new libs shouldn't be too difficult - although my dist will be enormous in comparison to what it was (~496K if I remember correctly - writing this from memory at 0228 so I don't forget).

There are also examples in the handbook I picked up, so hopefully I can make a forray into the RMI soon.

PS - I think that I probably annoyed the hell out of David at the convention, he sure seemed agitated. My apologies, but in my defense the system really isn't that simple for someone going from 0-60 in a whole new arena of technologies. It becomes easy after the several years of experience one from the project possesses... I'd also say that picking up a lot in a few days is a definately admirable and defensible position...

So after struggling with both Google's broken Base program, and this, and several other problems for a while I finally got the ref implementation working. It actually ended up being really counter-intuitive. I used keytool to generate new certificates with RSA, and just threw the exported .cer into the keytrust for both client and server. Which is odd, because I tried that, but apparently I was also cross-importing .cer files. I also tried doing a self-CA using openssl, which also should have worked. I kept getting no trusted certificate found

So apparently you don't need to use a CA, you don't need to cross-include (which is odd because they've got a default chain-of-trust of 1, which you'd think if you import it -trusted, or tell it to trust it should trust. But no. Apparently importing the CA's cert didn't help, but should have). I'm wondering if somehow I forgot to include RSA and it was using DSA. I sincerely hope that's what's going on, because I don't see how the hell all this trouble arose. Although, in all fairness I did spend most of my time trying to get Google to work... yay for juggling job responsibilities.

Edit

Reflecting upon the above - if it was just a question of using the wrong algorithm, it would have worked when I used the ofbizssl.jks keystore key. Although, if both client and server needed, for some odd reason, to encrypt things, then it would need both to be RSA. I just don't know enough, and my packet sniffing just didn't find enough useful material, other than I guess the client does lists the object, the server lists the stub, then the server starts throwing certs at it and the client sees if it's good. I also have the sneaking suspicion that I was breaking in multiple places (server cert, something about the client (which shouldn't need more than the pubkey of the server with standard SSL), validation, I got bad cert a few times) and was getting really odd errors.

Interesting to note: my certs also seem to have only been generated for a month, so we'll see where this takes me.

PS - there's also http://ofbizwiki.go-integral.com/Wiki.jsp?page=UsingNonSSLRMI which tells you how to set it up NOT to use SSL, but that isn't what I was after

End Edit

TODO: fix netbeans class issue (it's apparently ignoring my env setting for libs, lovely).

I ended up opening up the userLogin service, and I'm going to need to go and export a bunch of other services (like prodFindProduct or whatever calls it). Thankfully they have a master reference, which I might add is a lovely creation.

Journaling

It appears that OFBiz has transaction logs that I may be able to tap into, depending on how I do order transactions. But, because transactions are very heavy for serialization of large objects the question is then what do we store on the server and what do we store on the client. If you can guarantee high performance networks you might choose all on the server, but since I have no guarantee of the network segment I'm running on, I chose to log only what naturally belongs there - orders, daily stats (although this may actually just go on the registers), and to store the rest clientside.

The client will have a richer log, including actions not relevent to the business process, and will be aggregate such that you can write "reports" against it. I plan on embedding a database and writing flatfiles because I don't particularly care about state. This is raw data, and I want raw data processing power. I'm currently investigating HSQL as I know it's fast and supposed to be easy to integrate. SQLite is another contender. DB4O, Derby or JavaDB may also be considered, should they be required.

Right now preliminary investigation has yielded a performance report (PDF) by PolePosition, demonstrating the fact that HSQL is indeed fast from Java, especially if you don't care about rich object hierarchies. I'm not sure about ACID or about standard RDBMS features, but I really shouldn't need much - aggregation fuctions such as SUM() and COUNT(), SELECT (project) support should do me fine.

All reports will be run against local copy, unless I figure out some reason not to.


This page is CategoryJPoS

There are no comments on this page. [Add comment]

Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.3
Page was generated in 0.0988 seconds