Hyperledger Composer - DateTime storage in asset - hyperledger-composer

This question is based upon my attemp to adapt the sample 'perishable-network' (https://github.com/hyperledger/composer-sample-networks/tree/master/packages/perishable-network) for my work.
Suppose I have an hyperledger composer asset called ShippingContract. Now I'd like to record the contract creation time in this asset (say when a createContract() function is called ). How can I achieve this? I was using a DateTime member which was being set in chaincode.
The few articles/posts (some on SO itself) that talk about this suggest that we should not store random/current time in DateTime object through chaincode, as during consensus, each endorsing/committing node will come up with different value and lead to failure of transaction!
The perishable-network sample uses a DateTime member variable, but sets this using the setupdemo transaction timestamp value within the setupDemo transaction code itself!
const tomorrow = setupDemo.timestamp;
tomorrow.setDate(tomorrow.getDate() + 1);
contract.arrivalDateTime = tomorrow;
First question: How is it possible to refer to the transaction timestamp within the same transaction itself? Is this timestamp set when endorsers first endorse the transaction?
Second question:
I was thinking that instead of DateTime member variable, it might be better to use a String variable and set that to new Date().toString() (Javascript function) and then pass it as a parameter to the transaction processor function (instead of calculating it at run-time within the function). This way, since I'm passing in a fixed value instead of having the chaincode calculate it dynamically, I hope to overcome any issues with consensus.
Is this a good approach? Any issues therein? Any better way to do this?

Related

How to update Radis for dynamic values?

I am working with some coaching using Redis in Nodejs.
here is my code implimentation.
redis.get(key)
if(!key) {
redis.set(key, {"SomeValue": "SomeValue", "SomeAnohterValue":"SomeAnohterValue"}
}
return redis.get(key)
Till here everything works well.
But let's assume a situation where I need to get the value from a function call and set it to Redis and then I keep getting the same value from Redis whenever I want, in this case, I don't need to call the function again and again for getting the value.
But for an instance, the values have been changed or some more values have been added to my actual API call, now I need to call that function again to update the values again inside the Redis corresponding to that same key.
But I don't know how can I do this.
Any help would be appreciated.
Thank you in advanced.
First thing is that your initial code has a bug. You should use the set if not exist functionality that redis provides natively instead of doing check and set calls
What you are describing is called cache invalidation and is one of the hardest parts in software development
You need to do a 'notify' in some way when the value changes so that the fetchers know that it is time to grab the most up to date value.
One simple way would be to have a dirty boolean variable that is set to true when the value is updated and when fetching you check that variable. If dirty then get from redis and set to false else return the vue from prior

Store a sheet object in cache of my google app script [duplicate]

I am trying to develop a webapp using Google Apps Script to be embedded into a Google Site which simply displays the contents of a Google Sheet and filters it using some simple parameters. For the time being, at least. I may add more features later.
I got a functional app, but found that filtering could often take a while as the client sometimes had to wait up to 5 seconds for a response from the server. I decided that this was most likely due to the fact that I was loading the spreadsheet by ID using the SpreadsheetApp class every time it was called.
I decided to cache the spreadsheet values in my doGet function using the CacheService and retrieve the data from the cache each time instead.
However, for some reason this has meant that what was a 2-dimensional array is now treated as a 1-dimensional array. And, so, when displaying the data in an HTML table, I end up with a single column, with each cell being occupied by a single character.
This is how I have implemented the caching; as far as I can tell from the API reference I am not doing anything wrong:
function doGet() {
CacheService.getScriptCache().put('data', SpreadsheetApp
.openById('####')
.getActiveSheet()
.getDataRange()
.getValues());
return HtmlService
.createTemplateFromFile('index')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function getData() {
return CacheService.getScriptCache().get('data');
}
This is my first time developing a proper application using GAS (I have used it in Sheets before). Is there something very obvious I am missing? I didn't see any type restrictions on the CacheService reference page...
CacheService stores Strings, so objects such as your two-dimensional array will be coerced to Strings, which may not meet your needs.
Use the JSON utility to take control of the results.
myCache.put( 'tag', JSON.stringify( myObj ) );
...
var cachedObj = JSON.parse( myCache.get( 'tag' ) );
Cache expires. The put method, without an expirationInSeconds parameter expires in 10 minutes. If you need your data to stay alive for more than 10 minutes, you need to specify an expirationInSeconds, and the maximum is 6 hours. So, if you specifically do NOT need the data to expire, Cache might not be the best use.
You can use Cache for something like controlling how long a user can be logged in.
You could also try using a global variable, which some people would tell you to never use. To declare a global variable, define the variable outside of any function.

Google Classroom (PHP Client Services): Create CourseWork with Due Date but No set Due Time

I've been working on creating Google Classroom Classwork programmatically using the Google PHP api client services library. I am able to successfully create coursework, using: courses_courseWork->create, and passing a coursework object.
However, I can't seem to create a Course work object with a due date but no due time. Creating without a due date works fine, but if I just set a due date, it says that a due time object ( Google_Service_Classroom_TimeOfDay ) must also be sent. I've tried creating without setting hours / minutes / seconds / nanos, I've tried setting them to null, and I've tried unsetting the object properties after creating it.
When I look at a created ClassWork object (through the web interface, with no due date), the dueTime object property is just an empty array. I cannot for the life of me figure out how to pass that when creating with the API.
Thank you!
Your question is a little old, but in case someone else is having this issue, if you set a dueDate, you must also set a dueTime. This is a requirement from the API:
dueDate: object(Date):
Optional date, in UTC, that submissions for this course work are due.
This must be specified if dueTime is specified.
dueTime: object(TimeOfDay):
Optional time of day, in UTC, that submissions for this course work are due.
This must be specified if dueDate is specified.
See: https://developers.google.com/classroom/reference/rest/v1/courses.courseWork#CourseWorkState
Also, as noted, all create request dates and times should be converted to UTC. Depending on how your app is set up, this can quickly get a bit complicated...
It may be easiest to use a library like moment.js or luxon, etc. to manipulate the dates.
(I used moment.js, converted the moment datetime object to UTC, then converted the moment object .toArray, which I iterated through to create dueDate and dueTime objects for the request)

Improve Script performance by caching Spreadsheet values

I am trying to develop a webapp using Google Apps Script to be embedded into a Google Site which simply displays the contents of a Google Sheet and filters it using some simple parameters. For the time being, at least. I may add more features later.
I got a functional app, but found that filtering could often take a while as the client sometimes had to wait up to 5 seconds for a response from the server. I decided that this was most likely due to the fact that I was loading the spreadsheet by ID using the SpreadsheetApp class every time it was called.
I decided to cache the spreadsheet values in my doGet function using the CacheService and retrieve the data from the cache each time instead.
However, for some reason this has meant that what was a 2-dimensional array is now treated as a 1-dimensional array. And, so, when displaying the data in an HTML table, I end up with a single column, with each cell being occupied by a single character.
This is how I have implemented the caching; as far as I can tell from the API reference I am not doing anything wrong:
function doGet() {
CacheService.getScriptCache().put('data', SpreadsheetApp
.openById('####')
.getActiveSheet()
.getDataRange()
.getValues());
return HtmlService
.createTemplateFromFile('index')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function getData() {
return CacheService.getScriptCache().get('data');
}
This is my first time developing a proper application using GAS (I have used it in Sheets before). Is there something very obvious I am missing? I didn't see any type restrictions on the CacheService reference page...
CacheService stores Strings, so objects such as your two-dimensional array will be coerced to Strings, which may not meet your needs.
Use the JSON utility to take control of the results.
myCache.put( 'tag', JSON.stringify( myObj ) );
...
var cachedObj = JSON.parse( myCache.get( 'tag' ) );
Cache expires. The put method, without an expirationInSeconds parameter expires in 10 minutes. If you need your data to stay alive for more than 10 minutes, you need to specify an expirationInSeconds, and the maximum is 6 hours. So, if you specifically do NOT need the data to expire, Cache might not be the best use.
You can use Cache for something like controlling how long a user can be logged in.
You could also try using a global variable, which some people would tell you to never use. To declare a global variable, define the variable outside of any function.

Create SharePoint IF function Workflow

I am trying to update the date in a column based on the information contained in another column. I know it will be an "IF" function, but I am not getting the formula correct.
I need to update the due date column by adding the time based from the frequency columnn(week, day, month, etc...) to the completion date column....please help!
I would not use the Designer inside Visual Studio to handle an If-Clause. Reason: I didn't figure out how to use this and from other things lieke the While-Activity I read that this is much slower than a coded one.
For some handsome looking I would add "CodeActivity" and link/ invoke my method to this. Inside this method you could use
string frequency = workflowProperties.Item["name of other column"].ToString();
string oldDate = workflowProperties.Item["name of updating column"].ToString();
DateTime newDate = Convert.ToDateTime(oldDate);
if (String.Equals(frequency, "weekly", StringComparison.OrdinalIgnoreCase))
{
<your code like:> workflowProperties.Item["name of updating column"] = newDate.AddDays(7);
}
else if (...)
or use switch (frequency){}
Remind that workflowProperties.Item refers everytime to selected Item. Because this is a global variable inside your workflow, you can access to it from every method. If you don't understand this example, be free to ask.
Shegit

Resources