Category Archives: Uncategorized

A follow-up on my unlikely Doomsday Scenario for SQL Server On Premises

A few days ago I published a post that conjectured about a rather unlikely scenario regarding SQL Server On Premises.

I was basing my conjecture on one single fact: that native client connectivity to SQL Server On Premises through SNAC is no longer supported, and that from now on, the only supported way to connect from client apps will be through an expanded ODBC driver.

Between August and September 2016, the Microsoft SQLNCli team blog published the following posts:

ODBC Driver 13.1 for SQL Server Released

Preview Release of the SQL Server [C/C++] ODBC Driver 13 for Linux

These two posts open the door to a different kind of scenario:

SQL Server has become a multi-platform technology, and it makes more sense for the team in charge of connectitivy tools to offer the best tools for all platforms, but at the same time, this team has to strive for as much maintainability for these tools as it is possible. One way to achieve that is to look for an API that can connect to all platforms, and that clearly is ODBC.
The SQLNCli team is working on the double to include in these ODBC drivers support for all relevant technologies previously available through SNAC and OleDb.

Kind regards, GEN

Is it that the days of SQL Server On Premises are numbered?

To start from a cautionary standpoint, what I am stating is not even a rumour, it is rather a conjecture.

Is this a possible event that might happen soon?

Hmmm, I guess that the answer should be no, we could count on at least the next version of On Prem coming within two more years.

Is there any evidence of such a possibility?

Well, actually, yes, there is some clear evidence of something strange going on with SQL Server On Premises that has lead me to this conjecture:

https://msdn.microsoft.com/en-us/library/cc280510.aspx

The main point of this link states as follows:

Updated: August 8, 2016

Warning

SQL Server Native Client (SNAC) is not supported beyond SQL Server 2012. Avoid using SNAC in new development work, and plan to modify applications that currently use it. The Microsoft ODBC Driver for SQL Server provides native connectivity from Windows to Microsoft SQL Server and Microsoft Azure SQL Database.

As the old saying goes:

“When you have no Plan B, you don’t have any plans at all”, the cautionary advice would be to start making plans for an exit strategy, which, among other options, should include a migration to SQL Azure among the prominent alternatives.

Kind regards, GEN

 

Ese asunto de los cursores

Introducción

La idea básica de este post es avanzar un poco más en el análisis de las razones  por las cuales es recomendable evitar el uso de cursores.

Razones principales del impacto de los cursores server-side en los recursos del Database Engine

El Database Engine esta optimizado para procesar conjuntos de registros, de la misma forma que el lenguaje T-SQL es un lenguaje de tipo imperativo orientado a conjuntos de registros, donde los comandos indican el resultado a obtener en vez de detallar el camino para obtenerlo. En suma, tanto el Engine como T-SQL están diseñados de acuerdo con un esquema set-oriented.

Los cursores son un recurso programático que permite recuperar en memoria un conjunto de registros y procesarlos un registro por vez, es decir, operan con un esquema de tipo record-oriented.

En el caso de cursores implementados en T-SQL, para que el Database Engine pueda lograr que este tipo de recursos opere en forma adecuada y lo haga en armonía con el resto de sí mismo, necesita contener a los cursores en un entorno de ejecución propio, adecuado para el esquema record-oriented, que permita conservar la consistencia y armonía entre el cursor y el resto de las cosas que el Engine controla, que operan con el modelo set-oriented.

Dicho entorno de ejecución consume en forma significativa recursos compartidos y escasos, y esta es la razón principal por lo cual es tan generalizada la recomendación de evitar el uso de cursores, en particular, cursores server-side, tal como es el caso de los cursores implementados en T-SQL.

Por su parte, en el caso de los cursores server-side, la metadata del cursor, necesaria para su ejecución, es almacenada en memoria del mismo server, lo que agrava aún más la situación en relación al consumo de recursos compartidos y escasos de la instancia.

Otros problemas asociados al uso de cursores

Además de los problemas ya mencionados en relación al uso de cursores en T-SQL, es común que surjan algunos otros problemas que afectan al uso de recursos en una instancia durante la ejecución de una rutina basada en cursores T-SQL.

Estos problemas frecuentes son consecuencia del hecho que no se configura el cursor en forma adecuada según los requerimientos de la rutina que lo contiene.

Para ilustrar este tipo de problemas, usaremos como base de nuestro análisis un ejemplo típico de uso de cursores que podemos obtener haciendo una búsqueda en Internet.

Un ejemplo “clásico” podria ser algo así:

DECLARE @name VARCHAR(50) — database name

DECLARE @path VARCHAR(256) — path for backup files

DECLARE @fileName VARCHAR(256) — filename for backup

DECLARE @fileDate VARCHAR(20) — used for file name

SET @path = ‘C:\Backup\’

SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112)

DECLARE db_cursor CURSOR FOR

SELECT name

FROM MASTER.dbo.sysdatabases

WHERE name NOT IN (‘master’,’model’,’msdb’,’tempdb’)

OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @name

WHILE @@FETCH_STATUS = 0

BEGIN

SET @fileName = @path + @name + ‘_’ + @fileDate + ‘.BAK’

BACKUP DATABASE @name TO DISK = @fileName

FETCH NEXT FROM db_cursor INTO @name

END

CLOSE db_cursor

DEALLOCATE db_cursor

Vamos a usar para el análisis un ejemplo de cursores similar, con el mismo tipo de configuración de cursor no adecuada.

Vamos a usar la base de datos AventureWorks para este ejemplo (en realidad, una copia de la misma cuyo nombre es AW).

A fin de mostrar como afecta el uso de una configuración no adecuada del cursor, el ejemplo de código no cierra el cursor, es decir, lo deja abierto para ver que pasa con la base de datos afectada por un cursor con este tipo de configuración durante la ejecución del mismo.

El código de la rutina de ejemplo es el siguiente:

DECLARE @OrderQty int

DECLARE @QtyIncrease decimal(8, 3)

USE AW

DECLARE db_cursor CURSOR FOR

SELECT OrderQty from Sales_SalesOrderDetail order by SalesOrderDetailId

OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @OrderQty

BEGIN

SET @QtyIncrease = (@OrderQty * 1.25)

PRINT @QtyIncrease

FETCH NEXT FROM db_cursor INTO @OrderQty

END

Para analizar como un cursor con esta configuración afecta a la base de datos y a la instancia involucradas en su ejecución, usaremos el siguiente query con algunas DMVs adecuadas para el análisis de ejecución de cursores:

SELECT c.creation_time, c.cursor_id, c.name, c.session_id

,tl.resource_type

,tl.resource_description

,tl.request_session_id

,tl.request_mode

,tl.request_type

,tl.request_status

,tl.request_reference_count

,tl.request_lifetime

,tl.request_owner_type

,s.transaction_isolation_level

,s.login_time

,s.last_request_start_time

,s.last_request_end_time

,s.status

,s.program_name

,s.nt_user_name

FROM sys.dm_exec_cursors(0) AS c

inner JOIN sys.dm_exec_sessions AS s ON c.session_id = s.session_id

inner join sys.dm_tran_locks tl on

tl.request_session_id = s.session_id

GO

El resultado de este query es algo así:

 Result

Como se puede apreciar, durante la ejecución de un cursor con este tipo de configuración, el cursor aplica un lock a la base de datos que contiene a las tablas involucradas.

Dado que a propósito no hemos cerrado el cursor, podemos verificar el lock de la base de datos completa intentando hacer algún cambio a la misma que ponga de manifiesto dicho lock, como por ejemplo, intentar renombrarla.

Al intentar renombrar a la base de datos AW, despues de unos segundos SSMS retorna el siguiente mensaje de error:

Error_Message

La falta de la correcta configuración de los cursores server-side es un error muy común y generalizado.

Sin embargo, en este post no le dedicaremos tiempo a revisar los detalles de una correcta configuración de cursores server-side, dado que el objetivo principal del post es exponer las razones por las cuales no deberíamos usar cursores, y si hemos puesto el foco en exponer con ejemplos concretos algunas de las consecuencias negativas que explican porque no deberíamos usar cursores.

Saludos, GEN

¿ Qué es un objeto Sequence y en que escenarios se usa ?

En este post voy a tratar brevemente sobre que es un objeto de base de datos Sequence, y en que escenarios se usa.

Focalizaremos nuestra atención en este post en analizar el uso básico de Sequence, las comparaciones principales entre Identity y Sequence, y las principales razones de requerimientos funcionales que justifican el uso de objetos Sequence, pero tratar en otro post el análisis de razones técnicas para optar por el uso de Identity o de Sequence en determinados tipos de escenarios.

Los puntos principales de este post son los siguientes:

  • ¿ Qué es un objeto de base de datos Sequence ?
  • ¿ Qué similitudes y diferencias existen entre Sequence y Identity ?
  • Escenarios típicos donde se usa Sequence

¿ Qué es un objeto de base de datos Sequence ?

Un Sequence es un objeto de base de datos que permite recuperar el próximo valor numérico entero de una secuencia de números, configurada con un valor mínimo, un valor máximo, un valor inicial y un valor de paso o incremento.

Un objeto Sequence posee algunos elementos parecidos a un Identity, pero a diferencia de este último, el Sequence es un objeto de base de datos independiente de una tabla, mientras que un Identity es una propiedad de un campo de una tabla.

Es importante no confundir Sequence con Identity, por lo tanto, es conveniente que revisemos la sintaxis de la sentencia de creación de un Sequence a través de algunos ejemplos.

Antes de entrar de lleno a los ejemplos, es necesario destacar que la secuencia de valores de un objeto Sequence es un conjunto de números que define el dominio de dicho objeto, donde el dominio es el conjunto de valores válidos.

Dado que la operación básica con un objeto Sequence es la de recuperación del próximo valor en la secuencia, debemos tomar aquellas decisiones de diseño que nos aseguren que la lógica de la solución que opera con un objeto Sequence (en base a solicitar el próximo valor de la secuencia), lo haga a sabiendas que el próximo valor a recuperar pertenece al dominio del objeto Sequence a invocar, porque de lo contrario, el objeto Sequence arrojará una exception por haber solicitado un próximo valor cuando el dominio del mismo ya está agotado.

La sintaxis mínima de creación de un objeto Sequence es así:

CREATE SEQUENCE UnTurno;

GO

Esta sentencia no indica ningún valor numérico (ni un valor inicial, ni un valor mínimo, ni un valor máximo, ni un valor de paso o incremento), por lo tanto, el engine aplica los defaults de la sentencia para ejecutar el comando.

En este caso, los defaults aplicados son los siguientes:

El tipo de dato asignado al Sequence creado (dado que el comando usado no define un tipo de dato en particular para el objeto Sequence) es bigint.

El paso o incremento asignado al Sequence creado (dado que el comando no define paso o incremento) es +1, es decir, por defecto, es un Sequence ascendente de incremento unitario.

En este caso, tanto el valor mínimo como el valor inicial asignado al Sequence creado (dado que el comando no define ninguno de los dos) se corresponden con el valor mínimo del data type para un Sequence ascendente, o el valor máximo del data type para un Sequence descendente. En este caso, como el data type es bigint y el Sequence es ascendente por defecto, el valor mínimo y el valor inicial de este Sequence es el valor mínimo del data type bigint, es decir, el valor inicial es el número entero -9.223.372.036.854.775.808.

El valor máximo asignado al Sequence creado (dado que el comando no define un valor inicial) es el valor máximo del data type para un Sequence ascendente, o el valor mínimo del data type para un Sequence descendente. En este caso, como el data type es bigint y el Sequence es ascendente por defecto, el valor máximo de este Sequence es el valor máximo del data type bigint, es decir, el valor máximo es el número entero 9.223.372.036.854.775.807.

En este caso de comando mínimo que opera con todos los defaults, Sequence no usa Caché de números de la secuencia, ni recicla cuando llega al final de la secuencia: en aquellos casos como este, donde los límites de la secuencia (valores inicial y final) coinciden con los límites del data type asociado a dicha sequencia, el Sequence no puede reciclar.

Ya mencionamos al inicio del post que nos focalizaremos en las razones de uso del Sequences basadas en requerimientos funcionales y dejaremos para otro post el análisis de razones técnicas, por lo tanto, en estos ejercicios veremos el uso de Sequence con reciclado de dominio, pero no veremos el uso de Sequence con Caché, dado que los pros y contras de usar Sequence con Caché son principalmente técnicas y de Quality Attributes.

Tal como es esperable, contamos con una System View, sys.sequences, para consultar sobre la metadata y el estado actual de cada objeto Sequence de una base de datos dada:

SELECT * FROM sys.sequences WHERE name = N’UnTurno’;

Al revisar los detalles del Sequence creado en esta System View, podemos verificar que indica que tanto el valor inicial del mismo es el número -9.223.372.036.854.775.808, y el valor mínimo es también dicho número. De igual forma, podemos revisar el resto de los datos de metadata (valor máximo, incremento, valor actual del Sequence) del Sequence recién creado.

Para que un Sequence sea realmente útil, tenemos que ver que comando usar para recuperar el próximo valor de dicha secuencia:

SELECT NEXT VALUE FOR UnTurno;

Vemos que el valor que retorna este comando para el Sequence recién creado se corresponde con el valor inicial, es decir, en este caso retorna el valor -9.223.372.036.854.775.808.

Queda claro que si al crear un objeto Sequence no le definimos en forma explícita que pertenece a un Schema existente dado, por defecto pertenece al Schema dbo.

Veamos ahora un ejemplo algo más completo, donde definimos en forma explícita el data type, valor inicial, y paso o incremento del Sequence (usamos el data model OLTP de AdventureWorks para SQL Server 2012 en los ejemplos restantes):

USE AdventureWorks2012

GO

IF EXISTS (SELECT * FROM sys.sequences WHERE name = N’UnTurno’)

     DROP SEQUENCE UnTurno;

GO

CREATE SEQUENCE UnTurno AS tinyint

     START WITH 0

     INCREMENT BY 100;

GO

— Cuarto Select ha de fallar

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno; — <= Falla!

Era predecible que la cuarta invocación del “NEXT VALUE FOR” debe arrojar una exception, dado que queda fuera del rango válido de valores (fuera del dominio) que pertenecen a la secuencia configurada en el Sequence creado en este ejercicio.

En relación con los data types que se pueden usar para definir en un Sequence, podemos usar todos los data types de tipo entero built-in que soporta SQL Server, así como todos aquellos alias data types que hemos creado que referencian a cualquiera de los data types enteros built-in (un ejemplo con el uso de Sequence con alias data type es un caso de razón principalmente técnica, y no lo veremos en este post).

A continuación veremos cómo crear un objeto Sequence capaz de retornar valores de una secuencia periódica, y en este caso, definimos en forma explícita tanto el data type, como el valor inicial, el valor mínimo, el valor máximo y el paso o incremento. Para lograr esto, vamos a ver un caso con reciclado.

USE AdventureWorks2012

GO

IF EXISTS (SELECT * FROM sys.sequences WHERE name = N’UnTurno’)

     DROP SEQUENCE UnTurno;

GO

CREATE SEQUENCE UnTurno AS tinyint

     START WITH 0

     INCREMENT BY 1

     MINVALUE 0

     MAXVALUE 3

     CYCLE;

GO

— Estos selects no presentan falla

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

Al ejecutar todos estos “NEXT VALUE FOR”, se aprecia claramente el comportamiento periódico o cíclico de la secuencia configurada en el Sequence creado en este ejercicio, y como los parámetros de configuración del mismo determinan dicho comportamiento y el rango de valores del dominio de dicho período.

¿ Qué similitudes y diferencias existen entre Sequence y Identity?

Tal como hemos visto al comienzo de este post, la principal diferencia entre un objeto Sequence y Identity, es que el objeto Sequence es un objeto independiente, mientras que un Identity es una propiedad de una columna de una tabla.

Otras diferencias importantes entre Sequence y Identity es que un objeto Sequence solamente puede retornar valores numéricos de data types enteros, mientras que una columna con propiedad Identity puede estar asociada tanto a data types enteros como a data types con decimales: las columnas Identity solo pueden tener valores enteros, pero el uso de data types como el decimal(x,y) permite tener un rango de valores válidos más amplio que con la mayoría de los data types enteros (el soporte de decimal(18,0) en columas Identity tenía sentido antes de la inclusión del data type bigint).

Una diferencia a destacar es que Sequence permite crear secuencias periódicas de valores numéricos, mientras que Identity solamente puede crear secuencias no periódicas.

Otra diferencia relevante es que Sequence se puede usar en muchos contextos, como por ejemplo, para asignar en forma directa un valor a una variable, formando parte de una expresión en SELECTs, INSERTs o UPDATEs, mientras que un Identity solamente puede asignarle valor a la columna asociada en INSERTs.

En cuanto a las similitudes, ambos permiten crear secuencias de números con un valor inicial, un valor máximo, un valor de paso o incremento, tanto secuencias ascendentes como descendentes.

Un ejemplo sencillo de uso de Sequence con INSERTs y UPDATEs es el siguiente:

USE AdventureWorks2012

GO

IF EXISTS (SELECT * FROM sys.sequences WHERE name = N’UnTurno’)

     DROP SEQUENCE UnTurno;

GO

CREATE SEQUENCE UnTurno AS tinyint

     START WITH 0

     INCREMENT BY 1

     MINVALUE 0

     MAXVALUE 3

     CYCLE;

GO

CREATE TABLE data1

(col1 int not null);

GO

INSERT data1

VALUES (NEXT VALUE FOR UnTurno);

GO 10

UPDATE data1

SET col1 = NEXT VALUE FOR UnTurno;

SELECT col1 from data1;

Escenarios típicos donde se usa Sequence

Vamos a concentrar nuestra atención en algunos ejemplos de requerimientos funcionales que son adecuadamente implementados a través de objetos Sequence.

Por ejemplo, el tipo de requerimiento funcional que claramente se implementa en forma adecuada mediante objetos Sequence es el manejo de turnos por orden de llegada.

En diversos lugares de atención al público o a clientes, como en oficinas públicas o en bancos, es común que el esquema de atención al público es por estricto orden de llegada de los clientes. En forma tradicional, para administrar este manejo y evitar problemas con los clientes, se usan talonarios con tickets pre-impresos con una secuencia de números.

Más recientemente, las organizaciones han mostrado interés en implementar sistemas que emitan los tickets en forma automática, por lo tanto, es conveniente contar con mecanismos robustos que permitan generar secuencias configurables de números similares a las existentes en los talonarios de números.

Es conveniente presentar un caso concreto para apreciar cuan conveniente es usar un Sequence como base de la implementación de un requerimiento funcional de este tipo. Supongamos que tenemos que implementar una solución que sea capaz de generar turnos por orden de llegada en base a tickets numerados secuenciales cíclicos, con una secuencia de números entre 1 y 100, periódica o cíclica, que después del 100 recicle al número 1 y repita la secuencia.

A nivel de la capa de acceso a datos (SQL Server), la implementación tendrá un aspecto similar al siguiente:

USE AdventureWorks2012

GO

IF EXISTS (SELECT * FROM sys.sequences WHERE name = N’UnTurno’)

     DROP SEQUENCE UnTurno;

GO

CREATE SEQUENCE UnTurno AS tinyint

     START WITH 1

     INCREMENT BY 1

     MINVALUE 1

     MAXVALUE 100

     CYCLE;

GO

— Estos selects permiten probar la implementación

SELECT NEXT VALUE FOR UnTurno;

GO 98;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

SELECT NEXT VALUE FOR UnTurno;

Los SELECTs permiten ver como el Sequence ejecuta el reciclado y vuelve a repetir la secuencia de números del dominio en forma periódica, de tal forma que permite operar de igual forma que con un talonario de tickets pre-impreso que cuando se termina un talonario (con el Nro 100), se empieza a usar un nuevo talonario desde el comienzo, es decir, a partir del primer ticket que aparece, con el Nro 1.

 Con esto concluimos esta presentación introductoria del objeto de base de datos Sequence, donde se han expuesto ejemplos de escenarios funcionales que justifican su uso.

Saludos, GEN

 

Globalization and some challenges Agile teams are facing

Image

When it comes to the IT industry, some of the more important consequences of Globalization are Outsourcing of IT operations and Outsourcing of many software development posts.

Regarding the Outsourcing of software development posts, in general this has turned out to be a positive move for software companies and IT professionals in developing countries, as they have experienced a growth in their business operations driven by this process.

But this movement also has brought its own share of ills into the mix.

Now, the typical software development project has a team with team members from many countries, working across many time zones. The most frequent process used by these teams is Agile.

Let’s review some of the challenges that these Agile teams are facing, in no particular order.

One of such challenges is the diverse cultural backgrounds of team members. Even though diversity in general, and diverse cultural background in particular, is a very positive factor for an Agile team, the challenge that most frequently shows up is pertaining to communication.

One on one conversations between team members are a major aspect of Agile as a process, and diverse cultural backgrounds, including diverse native languages, pose some important issues and obstacles to the natural flow of the conversation.

[New comment added] It would make sense to expand this idea a little bit: outsourced team members in general do not belong to the same organization as the rest of the team, so, it is very likely that outsourced team members (developers) might not know the details of the business of the customer, or the meaning of business terms used by the customer when describing functional requirements and business rules (this relates to the concept of “ubiquitous language” in Domain Driven Development).

Besides this, different cultures usually have different cosmovisions, that is, different mappings to the concepts and ideas that explain the universe all around us. One of the first mappings that each person incorporates is their mother tongue, so, different native languages is an important element of the diverse ways of understanding the universe all around us. [New comment added]

But diverse cultural backgrounds is not the only challenge to one on one conversations, as all of these teams have non-collocated team members, and  that also poses a major obstacle to the flow of the conversation, at least to some of the conversations that are required to happen on a daily basis.

Another challenge is caused by the fact that team members that represent The Voice of the Customer are usually on a different “shore” from outsourced team members, most of them being developers, so, “up-close” conversations between developers and users also face some obstacles to be solved.

Another pattern that also is becoming important is that outsourced team members are also non-collocated among them, that is, outsourced team members from different regions of a country or from different countries of the world.

This pattern in particular is a major obstacle to Agile. This pattern affects many Agile practices, like one on one conversations, or even pair programming.

Another pattern that is becoming important is that all these constraints that affect these Agile teams introduce certain types of discontinuities to the process that induce issues and problems to the scalability of the team.

For instance, these constraints and discontinuities have to be mitigated with many calls and meetings of the leadership of the project, which means that team leaders are busy each and every day during a significant percentage of their available time, which means that they are not as available to team members as it would be recommended.

The principles of Agile are such that if Agile needs any fixing, it should be done from within, that is, by the team. So, in a coming post, we will discuss some solutions to these challenges.

Kind regards, GEN

Twelve years after: What (the heck) has happened to Agile?

Image

 

On February 11, 2013 (just a few days from now), we all will celebrate the 12th anniversary of that magical gathering of free wills, anarchist ideals (of the Molotov Cocktail style) and luminous thoughts that brought us The Agile Manifesto.

Before we get into the flesh of the matter, I would like to spend a few seconds (more like “a few tens of words”, being this just a blog post) expanding the ideas behind the title for this post.

To start with the main title, “Twelve years after”, I understand that some of you may realize the double entendre, with this last expression in french being what, a triple entendre?.

It is clear that the phrase “Twelve years after” has a clear “face value” meaning, since it has been 12 years since The Agile Manifesto was introduced.

Besides this clear meaning, there is wide open reference to Alexander Dumas’ novel, “Twenty Years After”, a sequel to The Three Musketeers novel (not among the most famous novels of Dumas, but one that I really enjoyed in my childhood). The reference to the novel is easy to figure out:

What has happened to those principles?

What has happened to all that courage?

What has happened to all that momentum?

It is even easier to realize that these questions perfectly apply to both situations of the double entendre (or was it is triple?):

just as “Twenty Years After” is an  essay on those questions applied to the story of the Musketeers, my post is an simple enquiry on the same questions applied to the Agile Movement.

Even though we all could recite it without a hitch, not even blinking an eye in the process, I would like to revisit the paragraphs of the bloody thang:

“We are uncovering better ways of developing

software by doing it and helping others do it.

Through this work we have come to value:

 

Individuals and interactions over processes and tools

Working software over comprehensive documentation

Customer collaboration over contract negotiation

Responding to change over following a plan

 

That is, while there is value in the items on

the right, we value the items on the left more.”

At this point, I would like to invite you all to do an internal reflection meeting with ourselves.

 

How much time do we spend on the GD plan?

How much time do we spend on the “eternal tug-o-war” of the SOW and the contract?

Why are we all against each other, instead of all of us together against the problems?

Where did all the fun that we used to have working together has gone?

What could we do to get rid of all these woes?

Stealing from some amazingly agile thoughts from one of the original signatories, let’s ponder about the actual DNA of Agile:

From SCRUM, Agile has gained a sense of self-organization.

From Extreme Programming, Agile has gained a sense of self-discipline.

From Crystal, Agile has gained a sense of self-awareness.

Stealing some other wonderful thoughts from Tony Hsieh:

“Deliver ‘WOW!’ through service.

Embrace and drive change.

Create fun and a little weirdness.

Be adventurous, creative and open-minded.

Pursue growth and learning.

Build open and honest relationships with communication.

Build a positive team and family spirit.

Do more with less.

Be passionate and determined.

Be humble.

Kind regards, GEN

  

Twitter now has its own hyperlink shortening service

Wonderful news! So now, we don’t have to spend time switching between twitter and own favorite link shortening service.